135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley/* 235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * Property Service contexts backend for labeling Android 335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * property keys 435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley */ 535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <stdarg.h> 735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <string.h> 835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <ctype.h> 935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <errno.h> 1035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <limits.h> 1135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <sys/types.h> 1235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include <sys/stat.h> 1335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include "callbacks.h" 1435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley#include "label_internal.h" 1535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 1635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley/* A property security context specification. */ 1735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleytypedef struct spec { 1835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct selabel_lookup_rec lr; /* holds contexts for lookup result */ 1935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley char *property_key; /* property key string */ 2035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} spec_t; 2135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 2235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley/* Our stored configuration */ 2335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystruct saved_data { 2435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* 2535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * The array of specifications is sorted for longest 2635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * prefix match 2735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley */ 2835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_t *spec_arr; 2935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int nspec; /* total number of specifications */ 3035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley}; 3135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 3235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic int cmp(const void *A, const void *B) 3335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 3435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley const struct spec *sp1 = A, *sp2 = B; 3535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 3635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (strncmp(sp1->property_key,"*",1) == 0) 3735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return 1; 3835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (strncmp(sp2->property_key,"*",1) == 0) 3935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 4035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 4135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley size_t L1 = strlen(sp1->property_key); 4235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley size_t L2 = strlen(sp2->property_key); 4335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 4435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return (L1 < L2) - (L1 > L2); 4535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 4635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 4735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley/* 4835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * Warn about duplicate specifications. 4935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley */ 5035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic int nodups_specs(struct saved_data *data, const char *path) 5135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 5235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley int rc = 0; 5335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int ii, jj; 5435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct spec *curr_spec, *spec_arr = data->spec_arr; 5535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 5635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley for (ii = 0; ii < data->nspec; ii++) { 5735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley curr_spec = &spec_arr[ii]; 5835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley for (jj = ii + 1; jj < data->nspec; jj++) { 5935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if ((!strcmp(spec_arr[jj].property_key, curr_spec->property_key))) { 6035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rc = -1; 6135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley errno = EINVAL; 6235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (strcmp 6335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley (spec_arr[jj].lr.ctx_raw, 6435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley curr_spec->lr.ctx_raw)) { 6535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log 6635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley (SELINUX_ERROR, 6735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley "%s: Multiple different specifications for %s (%s and %s).\n", 6835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley path, curr_spec->property_key, 6935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_arr[jj].lr.ctx_raw, 7035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley curr_spec->lr.ctx_raw); 7135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } else { 7235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log 7335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley (SELINUX_ERROR, 7435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley "%s: Multiple same specifications for %s.\n", 7535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley path, curr_spec->property_key); 7635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 7735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 7835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 7935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 8035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return rc; 8135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 8235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 8335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic int process_line(struct selabel_handle *rec, 8435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley const char *path, char *line_buf, 8535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley int pass, unsigned lineno) 8635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 8735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley int items, len; 8835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley char buf1[BUFSIZ], buf2[BUFSIZ]; 8935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley char *buf_p, *prop = buf1, *context = buf2; 9035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct saved_data *data = (struct saved_data *)rec->data; 9135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_t *spec_arr = data->spec_arr; 9235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int nspec = data->nspec; 9335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 9435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley len = strlen(line_buf); 9535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (line_buf[len - 1] == '\n') 9635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley line_buf[len - 1] = 0; 9735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley buf_p = line_buf; 9835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley while (isspace(*buf_p)) 9935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley buf_p++; 10035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* Skip comment lines and empty lines. */ 10135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (*buf_p == '#' || *buf_p == 0) 10235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return 0; 10335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley items = sscanf(line_buf, "%255s %255s", prop, context); 10435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (items != 2) { 10535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log(SELINUX_WARNING, 10635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley "%s: line %d is missing fields, skipping\n", path, 10735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley lineno); 10835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return 0; 10935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 11035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 11135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (pass == 1) { 11235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* On the second pass, process and store the specification in spec. */ 11335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_arr[nspec].property_key = strdup(prop); 11435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (!spec_arr[nspec].property_key) { 11535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log(SELINUX_WARNING, 11635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley "%s: out of memory at line %d on prop %s\n", 11735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley path, lineno, prop); 11835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 11935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 12035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 12135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 12235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_arr[nspec].lr.ctx_raw = strdup(context); 12335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (!spec_arr[nspec].lr.ctx_raw) { 12435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log(SELINUX_WARNING, 12535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley "%s: out of memory at line %d on context %s\n", 12635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley path, lineno, context); 12735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 12835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 12951c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig 13051c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig if (rec->validating) { 13151c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) { 13251c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig selinux_log(SELINUX_WARNING, 13351c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig "%s: line %d has invalid context %s\n", 13451c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig path, lineno, spec_arr[nspec].lr.ctx_raw); 13551c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig } 13651c57096c8101ea13e51c296e4891ae84fc1c422Robert Craig } 13735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 13835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 13935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley data->nspec = ++nspec; 14035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return 0; 14135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 14235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 143a2e47cd90d84d48cde19575d044577a3fc7a4000Stephen Smalleystatic int init(struct selabel_handle *rec, const struct selinux_opt *opts, 14435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned n) 14535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 14635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct saved_data *data = (struct saved_data *)rec->data; 14735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley const char *path = NULL; 14835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley FILE *fp; 14935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley char line_buf[BUFSIZ]; 15035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int lineno = 0, maxnspec, pass; 15135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley int status = -1; 15235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct stat sb; 15335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 15435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* Process arguments */ 15535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley while (n--) 15635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley switch (opts[n].type) { 15735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley case SELABEL_OPT_PATH: 15835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley path = opts[n].value; 15935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley break; 16035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 16135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 16235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* Open the specification file. */ 16335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if ((fp = fopen(path, "r")) == NULL) 16435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 16535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 16635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (fstat(fileno(fp), &sb) < 0) 16735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 16835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (!S_ISREG(sb.st_mode)) { 16935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley errno = EINVAL; 17035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 17135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 17235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 17335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* 17435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * Two passes of the specification file. First is to get the size. 17535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * After the first pass, the spec array is malloced to the appropriate 17635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * size. Second pass is to populate the spec array and check for 17735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * dups. 17835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley */ 17935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley maxnspec = UINT_MAX / sizeof(spec_t); 18035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley for (pass = 0; pass < 2; pass++) { 18135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley data->nspec = 0; 18235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 18335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley while (fgets(line_buf, sizeof line_buf - 1, fp) 18435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley && data->nspec < maxnspec) { 18535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (process_line(rec, path, line_buf, pass, ++lineno) != 0) { 18635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 18735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 18835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 18935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 19035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (pass == 1) { 19135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley status = nodups_specs(data, path); 19235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 19335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (status) 19435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 19535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 19635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 19735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (pass == 0) { 19835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 19935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (data->nspec == 0) { 20035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley status = 0; 20135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 20235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 20335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 20435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (NULL == (data->spec_arr = 20535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley malloc(sizeof(spec_t) * data->nspec))) 20635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 20735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 20835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley memset(data->spec_arr, 0, sizeof(spec_t)*data->nspec); 20935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley maxnspec = data->nspec; 21035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rewind(fp); 21135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 21235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 21335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 21435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley qsort(data->spec_arr, data->nspec, sizeof(struct spec), cmp); 21535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 21635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley status = 0; 21735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleyfinish: 21835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley fclose(fp); 21935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return status; 22035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 22135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 22235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley/* 22335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley * Backend interface routines 22435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley */ 22535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic void closef(struct selabel_handle *rec) 22635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 22735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct saved_data *data = (struct saved_data *)rec->data; 22835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct spec *spec; 22935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int i; 23035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 23135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley for (i = 0; i < data->nspec; i++) { 23235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec = &data->spec_arr[i]; 23335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley free(spec->property_key); 23435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley free(spec->lr.ctx_raw); 23535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley free(spec->lr.ctx_trans); 23635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 23735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 23835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (data->spec_arr) 23935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley free(data->spec_arr); 24035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 24135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley free(data); 24235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 24335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 24435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic struct selabel_lookup_rec *lookup(struct selabel_handle *rec, 24535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley const char *key, 24635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley int __attribute__((unused)) type) 24735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 24835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct saved_data *data = (struct saved_data *)rec->data; 24935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley spec_t *spec_arr = data->spec_arr; 25035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley unsigned int i; 25135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct selabel_lookup_rec *ret = NULL; 25235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 25335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (!data->nspec) { 25435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley errno = ENOENT; 25535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 25635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 25735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 25835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley for (i = 0; i < data->nspec; i++) { 25935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (strncmp(spec_arr[i].property_key, key, 26035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley strlen(spec_arr[i].property_key)) == 0) { 26135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley break; 26235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 26335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (strncmp(spec_arr[i].property_key, "*", 1) == 0) 26435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley break; 26535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 26635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 26735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (i >= data->nspec) { 26835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley /* No matching specification. */ 26935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley errno = ENOENT; 27035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley goto finish; 27135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley } 27235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 27335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley ret = &spec_arr[i].lr; 27435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 27535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleyfinish: 27635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return ret; 27735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 27835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 27935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalleystatic void stats(struct selabel_handle __attribute__((unused)) *rec) 28035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 28135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley selinux_log(SELINUX_WARNING, "'stats' functionality not implemented.\n"); 28235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 28335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 284a2e47cd90d84d48cde19575d044577a3fc7a4000Stephen Smalleyint selabel_property_init(struct selabel_handle *rec, 285a2e47cd90d84d48cde19575d044577a3fc7a4000Stephen Smalley const struct selinux_opt *opts, 286a2e47cd90d84d48cde19575d044577a3fc7a4000Stephen Smalley unsigned nopts) 28735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley{ 28835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley struct saved_data *data; 28935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 29035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley data = (struct saved_data *)malloc(sizeof(*data)); 29135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley if (!data) 29235b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return -1; 29335b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley memset(data, 0, sizeof(*data)); 29435b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 29535b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rec->data = data; 29635b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rec->func_close = &closef; 29735b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rec->func_stats = &stats; 29835b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley rec->func_lookup = &lookup; 29935b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley 30035b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley return init(rec, opts, nopts); 30135b01083fe5e34cbd318a78ef9b1a13432ae24d9Stephen Smalley} 302