113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Generalized labeling frontend for userspace object managers. 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil> 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h> 820271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh#include <ctype.h> 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h> 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 13e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines#include <sys/stat.h> 1420271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh#include <selinux/selinux.h> 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "callbacks.h" 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "label_internal.h" 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2084d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#ifdef NO_MEDIA_BACKEND 2184d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_MEDIA_BACKEND(fnptr) NULL 2284d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#else 2384d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_MEDIA_BACKEND(fnptr) &fnptr 2484d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#endif 2584d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts 2684d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#ifdef NO_X_BACKEND 2784d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_X_BACKEND(fnptr) NULL 2884d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#else 2984d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_X_BACKEND(fnptr) &fnptr 3084d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#endif 3184d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts 3284d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#ifdef NO_DB_BACKEND 3384d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_DB_BACKEND(fnptr) NULL 3484d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#else 3584d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#define CONFIG_DB_BACKEND(fnptr) &fnptr 3684d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts#endif 3784d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts 38e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis#ifdef NO_ANDROID_BACKEND 39e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis#define CONFIG_ANDROID_BACKEND(fnptr) NULL 40e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis#else 41e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis#define CONFIG_ANDROID_BACKEND(fnptr) (&(fnptr)) 42e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis#endif 43e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef int (*selabel_initfunc)(struct selabel_handle *rec, 45f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Haines const struct selinux_opt *opts, 46f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Haines unsigned nopts); 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic selabel_initfunc initfuncs[] = { 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &selabel_file_init, 5084d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts CONFIG_MEDIA_BACKEND(selabel_media_init), 5184d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts CONFIG_X_BACKEND(selabel_x_init), 5284d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts CONFIG_DB_BACKEND(selabel_db_init), 53e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis CONFIG_ANDROID_BACKEND(selabel_property_init), 54e029ace4d92eee8ba0990e1afbe356ae77b114ccJanis Danisevskis CONFIG_ANDROID_BACKEND(selabel_service_init), 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 57a00fd94a46e92a233f4e613660e9962918f28207Eamon Walshstatic void selabel_subs_fini(struct selabel_sub *ptr) 58a00fd94a46e92a233f4e613660e9962918f28207Eamon Walsh{ 5920271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh struct selabel_sub *next; 6020271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh 6120271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh while (ptr) { 6220271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh next = ptr->next; 6320271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh free(ptr->src); 6420271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh free(ptr->dst); 6520271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh free(ptr); 6620271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh ptr = next; 6720271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 6820271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh} 6920271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh 70a00fd94a46e92a233f4e613660e9962918f28207Eamon Walshstatic char *selabel_sub(struct selabel_sub *ptr, const char *src) 7120271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh{ 7220271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh char *dst = NULL; 7322671378f1ace857be4697a3b3aaf1645076d398Dan Walsh int len; 74a00fd94a46e92a233f4e613660e9962918f28207Eamon Walsh 7520271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh while (ptr) { 7620271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh if (strncmp(src, ptr->src, ptr->slen) == 0 ) { 7720271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh if (src[ptr->slen] == '/' || 7820271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh src[ptr->slen] == 0) { 7922671378f1ace857be4697a3b3aaf1645076d398Dan Walsh if ((src[ptr->slen] == '/') && 8022671378f1ace857be4697a3b3aaf1645076d398Dan Walsh (strcmp(ptr->dst, "/") == 0)) 8122671378f1ace857be4697a3b3aaf1645076d398Dan Walsh len = ptr->slen + 1; 8222671378f1ace857be4697a3b3aaf1645076d398Dan Walsh else 8322671378f1ace857be4697a3b3aaf1645076d398Dan Walsh len = ptr->slen; 8422671378f1ace857be4697a3b3aaf1645076d398Dan Walsh if (asprintf(&dst, "%s%s", ptr->dst, &src[len]) < 0) 852ca19f3f676a2747a38cf2d7dcf5037ccc8a9eb1Dan Walsh return NULL; 8620271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh return dst; 8720271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 8820271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 8920271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh ptr = ptr->next; 9020271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 9120271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh return NULL; 9220271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh} 9320271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh 94e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Hainesstruct selabel_sub *selabel_subs_init(const char *path, 95e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct selabel_sub *list, 96e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct selabel_digest *digest) 9720271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh{ 9820271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh char buf[1024]; 9920b43b3fd3d392c4f12a963a4e46c264e7ed5163Daniel J Walsh FILE *cfg = fopen(path, "r"); 100e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct selabel_sub *sub = NULL; 101e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct stat sb; 102a00fd94a46e92a233f4e613660e9962918f28207Eamon Walsh 103023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (!cfg) 104023c9c1fdee963606d830b70db108bd9031390f4Eric Paris return list; 105023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 106e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (fstat(fileno(cfg), &sb) < 0) 107e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return list; 108e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 109023c9c1fdee963606d830b70db108bd9031390f4Eric Paris while (fgets_unlocked(buf, sizeof(buf) - 1, cfg)) { 110023c9c1fdee963606d830b70db108bd9031390f4Eric Paris char *ptr = NULL; 111023c9c1fdee963606d830b70db108bd9031390f4Eric Paris char *src = buf; 112023c9c1fdee963606d830b70db108bd9031390f4Eric Paris char *dst = NULL; 113023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 114023c9c1fdee963606d830b70db108bd9031390f4Eric Paris while (*src && isspace(*src)) 115023c9c1fdee963606d830b70db108bd9031390f4Eric Paris src++; 116023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (src[0] == '#') continue; 117023c9c1fdee963606d830b70db108bd9031390f4Eric Paris ptr = src; 118023c9c1fdee963606d830b70db108bd9031390f4Eric Paris while (*ptr && ! isspace(*ptr)) 119023c9c1fdee963606d830b70db108bd9031390f4Eric Paris ptr++; 120023c9c1fdee963606d830b70db108bd9031390f4Eric Paris *ptr++ = '\0'; 121023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (! *src) continue; 122023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 123023c9c1fdee963606d830b70db108bd9031390f4Eric Paris dst = ptr; 124023c9c1fdee963606d830b70db108bd9031390f4Eric Paris while (*dst && isspace(*dst)) 125023c9c1fdee963606d830b70db108bd9031390f4Eric Paris dst++; 126023c9c1fdee963606d830b70db108bd9031390f4Eric Paris ptr=dst; 127023c9c1fdee963606d830b70db108bd9031390f4Eric Paris while (*ptr && ! isspace(*ptr)) 128023c9c1fdee963606d830b70db108bd9031390f4Eric Paris ptr++; 129023c9c1fdee963606d830b70db108bd9031390f4Eric Paris *ptr='\0'; 130023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (! *dst) 131023c9c1fdee963606d830b70db108bd9031390f4Eric Paris continue; 132023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 133023c9c1fdee963606d830b70db108bd9031390f4Eric Paris sub = malloc(sizeof(*sub)); 134023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (! sub) 135023c9c1fdee963606d830b70db108bd9031390f4Eric Paris goto err; 136023c9c1fdee963606d830b70db108bd9031390f4Eric Paris memset(sub, 0, sizeof(*sub)); 137023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 138023c9c1fdee963606d830b70db108bd9031390f4Eric Paris sub->src=strdup(src); 139023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (! sub->src) 140023c9c1fdee963606d830b70db108bd9031390f4Eric Paris goto err; 141023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 142023c9c1fdee963606d830b70db108bd9031390f4Eric Paris sub->dst=strdup(dst); 143023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (! sub->dst) 144023c9c1fdee963606d830b70db108bd9031390f4Eric Paris goto err; 145023c9c1fdee963606d830b70db108bd9031390f4Eric Paris 146023c9c1fdee963606d830b70db108bd9031390f4Eric Paris sub->slen = strlen(src); 147023c9c1fdee963606d830b70db108bd9031390f4Eric Paris sub->next = list; 148023c9c1fdee963606d830b70db108bd9031390f4Eric Paris list = sub; 14920271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 150e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 151e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (digest_add_specfile(digest, cfg, NULL, sb.st_size, path) < 0) 152e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines goto err; 153e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 154023c9c1fdee963606d830b70db108bd9031390f4Eric Parisout: 155023c9c1fdee963606d830b70db108bd9031390f4Eric Paris fclose(cfg); 156a00fd94a46e92a233f4e613660e9962918f28207Eamon Walsh return list; 157023c9c1fdee963606d830b70db108bd9031390f4Eric Pariserr: 158023c9c1fdee963606d830b70db108bd9031390f4Eric Paris if (sub) 159023c9c1fdee963606d830b70db108bd9031390f4Eric Paris free(sub->src); 160023c9c1fdee963606d830b70db108bd9031390f4Eric Paris free(sub); 161023c9c1fdee963606d830b70db108bd9031390f4Eric Paris goto out; 16220271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh} 16320271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh 164e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Hainesstatic inline struct selabel_digest *selabel_is_digest_set 165e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines (const struct selinux_opt *opts, 166e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines unsigned n, 167e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct selabel_digest *entry) 168e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines{ 169e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines struct selabel_digest *digest = NULL; 170e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 171e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines while (n--) { 172e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (opts[n].type == SELABEL_OPT_DIGEST && 173e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines opts[n].value == (char *)1) { 174e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines digest = calloc(1, sizeof(*digest)); 175e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (!digest) 176e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines goto err; 177e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 178e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines digest->digest = calloc(1, DIGEST_SPECFILE_SIZE + 1); 179e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (!digest->digest) 180e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines goto err; 181e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 182e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines digest->specfile_list = calloc(DIGEST_FILES_MAX, 183e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines sizeof(char *)); 184e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (!digest->specfile_list) 185e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines goto err; 186e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 187e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines entry = digest; 188e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return entry; 189e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines } 190e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines } 191e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return NULL; 192e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 193e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haineserr: 194e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(digest->digest); 195e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(digest->specfile_list); 196e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(digest); 197e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return NULL; 198e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines} 199e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 200e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Hainesstatic void selabel_digest_fini(struct selabel_digest *ptr) 201e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines{ 202e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines int i; 203e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 204e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(ptr->digest); 205e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(ptr->hashbuf); 206e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 207e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (ptr->specfile_list) { 208e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines for (i = 0; ptr->specfile_list[i]; i++) 209e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(ptr->specfile_list[i]); 210e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(ptr->specfile_list); 211e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines } 212e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines free(ptr); 213e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines} 214e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Validation functions 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 219f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Hainesstatic inline int selabel_is_validate_set(const struct selinux_opt *opts, 220f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Haines unsigned n) 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (n--) 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (opts[n].type == SELABEL_OPT_VALIDATE) 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return !!opts[n].value; 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint selabel_validate(struct selabel_handle *rec, 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct selabel_lookup_rec *contexts) 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc = 0; 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!rec->validating || contexts->validated) 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = selinux_validate(&contexts->ctx_raw); 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle contexts->validated = 1; 24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleout: 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return rc; 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 246e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines/* Public API helpers */ 247e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesstatic char *selabel_sub_key(struct selabel_handle *rec, const char *key) 248e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 249e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines char *ptr = NULL; 250e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines char *dptr = NULL; 251e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 252e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = selabel_sub(rec->subs, key); 253e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (ptr) { 254e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines dptr = selabel_sub(rec->dist_subs, ptr); 255e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (dptr) { 256e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines free(ptr); 257e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = dptr; 258e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 259e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } else { 260e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = selabel_sub(rec->dist_subs, key); 261e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 262e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (ptr) 263e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return ptr; 264e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 265e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 266e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 267e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 268e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesstatic int selabel_fini(struct selabel_handle *rec, 269e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines struct selabel_lookup_rec *lr, 270e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines int translating) 271e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 27250400d38203e4db08314168e60c281cc61a717a8dcashman char *path = NULL; 27350400d38203e4db08314168e60c281cc61a717a8dcashman 27450400d38203e4db08314168e60c281cc61a717a8dcashman if (rec->spec_files) 27550400d38203e4db08314168e60c281cc61a717a8dcashman path = rec->spec_files[0]; 27650400d38203e4db08314168e60c281cc61a717a8dcashman if (compat_validate(rec, lr, path, 0)) 277e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 278e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 279e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (translating && !lr->ctx_trans && 280e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans)) 281e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 282e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 283e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return 0; 284e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 285e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 286e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesstatic struct selabel_lookup_rec * 287e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesselabel_lookup_common(struct selabel_handle *rec, int translating, 288e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, int type) 289e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 290e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines struct selabel_lookup_rec *lr; 291e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines char *ptr = NULL; 292e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 293e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (key == NULL) { 294e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines errno = EINVAL; 295e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 296e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 297e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 298e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = selabel_sub_key(rec, key); 299e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (ptr) { 300e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = rec->func_lookup(rec, ptr, type); 301e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines free(ptr); 302e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } else { 303e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = rec->func_lookup(rec, key, type); 304e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 305e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!lr) 306e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 307e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 308e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (selabel_fini(rec, lr, translating)) 309e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 310e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 311e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return lr; 312e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 313e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 314e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesstatic struct selabel_lookup_rec * 315e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesselabel_lookup_bm_common(struct selabel_handle *rec, int translating, 316e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, int type, const char **aliases) 317e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 318e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines struct selabel_lookup_rec *lr; 319e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines char *ptr = NULL; 320e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 321e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (key == NULL) { 322e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines errno = EINVAL; 323e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 324e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 325e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 326e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = selabel_sub_key(rec, key); 327e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (ptr) { 328e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = rec->func_lookup_best_match(rec, ptr, aliases, type); 329e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines free(ptr); 330e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } else { 331e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = rec->func_lookup_best_match(rec, key, aliases, type); 332e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 333e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!lr) 334e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 335e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 336e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (selabel_fini(rec, lr, translating)) 337e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return NULL; 338e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 339e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return lr; 340e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 341e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Public API 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct selabel_handle *selabel_open(unsigned int backend, 347f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Haines const struct selinux_opt *opts, 348f2cd2f821fa34e8c7a12744626e19208463aa4e2Richard Haines unsigned nopts) 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct selabel_handle *rec = NULL; 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (backend >= ARRAY_SIZE(initfuncs)) { 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle errno = EINVAL; 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35784d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts if (!initfuncs[backend]) { 35884d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts errno = ENOTSUP; 35984d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts goto out; 36084d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts } 36184d07ebd48c85902c8ac54359f2b345881f64ad2William Roberts 36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rec = (struct selabel_handle *)malloc(sizeof(*rec)); 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!rec) 36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(rec, 0, sizeof(*rec)); 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rec->backend = backend; 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rec->validating = selabel_is_validate_set(opts, nopts); 36920b43b3fd3d392c4f12a963a4e46c264e7ed5163Daniel J Walsh 37020b43b3fd3d392c4f12a963a4e46c264e7ed5163Daniel J Walsh rec->subs = NULL; 371fd56c5230cea6b81fbe74d1d0a228936a6797923Dan Walsh rec->dist_subs = NULL; 372e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines rec->digest = selabel_is_digest_set(opts, nopts, rec->digest); 37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((*initfuncs[backend])(rec, opts, nopts)) { 37550400d38203e4db08314168e60c281cc61a717a8dcashman selabel_close(rec); 37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rec = NULL; 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleout: 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return rec; 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 382e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesint selabel_lookup(struct selabel_handle *rec, char **con, 383e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, int type) 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 38520271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh struct selabel_lookup_rec *lr; 38616a37c9f94c1e2dfb865e17e4200d2824d4971f5Richard Haines 387e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = selabel_lookup_common(rec, 1, key, type); 388e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!lr) 389e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 39016a37c9f94c1e2dfb865e17e4200d2824d4971f5Richard Haines 391e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines *con = strdup(lr->ctx_trans); 392e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return *con ? 0 : -1; 393e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 394e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 395e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesint selabel_lookup_raw(struct selabel_handle *rec, char **con, 396e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, int type) 397e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 398e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines struct selabel_lookup_rec *lr; 399e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 400e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = selabel_lookup_common(rec, 0, key, type); 401e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!lr) 402e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 403e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 404e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines *con = strdup(lr->ctx_raw); 405e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return *con ? 0 : -1; 406e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines} 407e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 408e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesbool selabel_partial_match(struct selabel_handle *rec, const char *key) 409e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines{ 410e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines char *ptr; 411e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines bool ret; 412e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 413e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!rec->func_partial_match) { 414e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines /* 415e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines * If the label backend does not support partial matching, 416e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines * then assume a match is possible. 417e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines */ 418e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return true; 419fd56c5230cea6b81fbe74d1d0a228936a6797923Dan Walsh } 420e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 421e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ptr = selabel_sub_key(rec, key); 42220271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh if (ptr) { 423e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ret = rec->func_partial_match(rec, ptr); 42420271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh free(ptr); 42520271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } else { 426e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines ret = rec->func_partial_match(rec, key); 42720271d94ed2b26b94b052ba6ed90b63566cecbb7Daniel J Walsh } 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 429e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return ret; 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 432e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesint selabel_lookup_best_match(struct selabel_handle *rec, char **con, 433e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, const char **aliases, int type) 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct selabel_lookup_rec *lr; 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 437e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!rec->func_lookup_best_match) { 438e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines errno = ENOTSUP; 439e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 440e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 441e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 442e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = selabel_lookup_bm_common(rec, 1, key, type, aliases); 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!lr) 44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *con = strdup(lr->ctx_trans); 44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *con ? 0 : -1; 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 450e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Hainesint selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con, 451e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines const char *key, const char **aliases, int type) 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct selabel_lookup_rec *lr; 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 455e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines if (!rec->func_lookup_best_match) { 456e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines errno = ENOTSUP; 457e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines return -1; 458e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines } 459e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines 460e7f970ffd1a8dbb26051405719a2288d34e856f6Richard Haines lr = selabel_lookup_bm_common(rec, 0, key, type, aliases); 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!lr) 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *con = strdup(lr->ctx_raw); 46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *con ? 0 : -1; 46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4686f295008efd72baac05ecd88587b706e50a77e49Stephen Smalleyenum selabel_cmp_result selabel_cmp(struct selabel_handle *h1, 4696f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley struct selabel_handle *h2) 4706f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley{ 4716f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley if (!h1->func_cmp || h1->func_cmp != h2->func_cmp) 4726f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley return SELABEL_INCOMPARABLE; 4736f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley 4746f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley return h1->func_cmp(h1, h2); 4756f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley} 4766f295008efd72baac05ecd88587b706e50a77e49Stephen Smalley 477e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Hainesint selabel_digest(struct selabel_handle *rec, 478e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines unsigned char **digest, size_t *digest_len, 479e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines char ***specfiles, size_t *num_specfiles) 480e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines{ 481e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (!rec->digest) { 482e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines errno = EINVAL; 483e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return -1; 484e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines } 485e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 486e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines *digest = rec->digest->digest; 487e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines *digest_len = DIGEST_SPECFILE_SIZE; 488e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines *specfiles = rec->digest->specfile_list; 489e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines *num_specfiles = rec->digest->specfile_cnt; 490e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines return 0; 491e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines} 492e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid selabel_close(struct selabel_handle *rec) 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 49550400d38203e4db08314168e60c281cc61a717a8dcashman size_t i; 496a00fd94a46e92a233f4e613660e9962918f28207Eamon Walsh selabel_subs_fini(rec->subs); 497fd56c5230cea6b81fbe74d1d0a228936a6797923Dan Walsh selabel_subs_fini(rec->dist_subs); 49850400d38203e4db08314168e60c281cc61a717a8dcashman if (rec->spec_files) { 49950400d38203e4db08314168e60c281cc61a717a8dcashman for (i = 0; i < rec->spec_files_len; i++) 50050400d38203e4db08314168e60c281cc61a717a8dcashman free(rec->spec_files[i]); 50150400d38203e4db08314168e60c281cc61a717a8dcashman free(rec->spec_files); 50250400d38203e4db08314168e60c281cc61a717a8dcashman } 503e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines if (rec->digest) 504e40bbea95f555fe9708cbbc39895bd67a8ac6c48Richard Haines selabel_digest_fini(rec->digest); 50550400d38203e4db08314168e60c281cc61a717a8dcashman if (rec->func_close) 50650400d38203e4db08314168e60c281cc61a717a8dcashman rec->func_close(rec); 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(rec); 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid selabel_stats(struct selabel_handle *rec) 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rec->func_stats(rec); 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 514