static int selabel_fini(struct selabel_handle *rec, struct selabel_lookup_rec *lr, int translating) { if (compat_validate(rec, lr, rec->spec_file, 0)) return -1; if (translating && !lr->ctx_trans && selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans)) return -1; return 0; }
static struct selabel_lookup_rec * selabel_lookup_common(struct selabel_handle *rec, int translating, const char *key, int type) { struct selabel_lookup_rec *lr; char *ptr = NULL; char *dptr = NULL; if (key == NULL) { errno = EINVAL; return NULL; } ptr = selabel_sub(rec->subs, key); if (ptr) { dptr = selabel_sub(rec->dist_subs, ptr); if (dptr) { free(ptr); ptr = dptr; } } else { ptr = selabel_sub(rec->dist_subs, key); } if (ptr) { lr = rec->func_lookup(rec, ptr, type); free(ptr); } else { lr = rec->func_lookup(rec, key, type); } if (!lr) return NULL; if (compat_validate(rec, lr, rec->spec_file, 0)) return NULL; if (translating && !lr->ctx_trans && selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans)) return NULL; return lr; }
static int process_line(struct selabel_handle *rec, const char *path, const char *prefix, char *line_buf, int pass, unsigned lineno) { int items, len; char *buf_p, *regex, *type, *context; struct saved_data *data = (struct saved_data *)rec->data; spec_t *spec_arr = data->spec_arr; unsigned int nspec = data->nspec; len = strlen(line_buf); if (line_buf[len - 1] == '\n') line_buf[len - 1] = 0; buf_p = line_buf; while (isspace(*buf_p)) buf_p++; /* Skip comment lines and empty lines. */ if (*buf_p == '#' || *buf_p == 0) return 0; items = sscanf(line_buf, "%as %as %as", ®ex, &type, &context); if (items < 2) { COMPAT_LOG(SELINUX_WARNING, "%s: line %d is missing fields, skipping\n", path, lineno); if (items == 1) free(regex); return 0; } else if (items == 2) { /* The type field is optional. */ free(context); context = type; type = 0; } len = get_stem_from_spec(regex); if (len && prefix && strncmp(prefix, regex, len)) { /* Stem of regex does not match requested prefix, discard. */ free(regex); free(type); free(context); return 0; } if (pass == 1) { /* On the second pass, process and store the specification in spec. */ char *errbuf = NULL; spec_arr[nspec].stem_id = find_stem_from_spec(data, regex); spec_arr[nspec].regex_str = regex; if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) { COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid regex %s: %s\n", path, lineno, regex, (errbuf ? errbuf : "out of memory")); } /* Convert the type string to a mode format */ spec_arr[nspec].type_str = type; spec_arr[nspec].mode = 0; if (!type) goto skip_type; len = strlen(type); if (type[0] != '-' || len != 2) { COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid file type %s\n", path, lineno, type); return 0; } switch (type[1]) { case 'b': spec_arr[nspec].mode = S_IFBLK; break; case 'c': spec_arr[nspec].mode = S_IFCHR; break; case 'd': spec_arr[nspec].mode = S_IFDIR; break; case 'p': spec_arr[nspec].mode = S_IFIFO; break; case 'l': spec_arr[nspec].mode = S_IFLNK; break; case 's': spec_arr[nspec].mode = S_IFSOCK; break; case '-': spec_arr[nspec].mode = S_IFREG; break; default: COMPAT_LOG(SELINUX_WARNING, "%s: line %d has invalid file type %s\n", path, lineno, type); return 0; } skip_type: spec_arr[nspec].lr.ctx_raw = context; /* Determine if specification has * any meta characters in the RE */ spec_hasMetaChars(&spec_arr[nspec]); if (strcmp(context, "<<none>>") && rec->validating) compat_validate(rec, &spec_arr[nspec].lr, path, lineno); } data->nspec = ++nspec; if (pass == 0) { free(regex); if (type) free(type); free(context); } return 0; }