int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) { type_datum_t *src, *tgt; class_datum_t *cls; perm_datum_t *perm; avtab_datum_t *av; avtab_key_t key; src = hashtab_search(policy->p_types.table, s); if (src == NULL) { fprintf(stderr, "source type %s does not exist\n", s); return 2; } tgt = hashtab_search(policy->p_types.table, t); if (tgt == NULL) { fprintf(stderr, "target type %s does not exist\n", t); return 2; } cls = hashtab_search(policy->p_classes.table, c); if (cls == NULL) { fprintf(stderr, "class %s does not exist\n", c); return 2; } perm = hashtab_search(cls->permissions.table, p); if (perm == NULL) { if (cls->comdatum == NULL) { fprintf(stderr, "perm %s does not exist in class %s\n", p, c); return 2; } perm = hashtab_search(cls->comdatum->permissions.table, p); if (perm == NULL) { fprintf(stderr, "perm %s does not exist in class %s\n", p, c); return 2; } } // See if there is already a rule key.source_type = src->s.value; key.target_type = tgt->s.value; key.target_class = cls->s.value; key.specified = AVTAB_ALLOWED; av = avtab_search(&policy->te_avtab, &key); if (av == NULL) { int ret; av = cmalloc(sizeof av); av->data |= 1U << (perm->s.value - 1); ret = avtab_insert(&policy->te_avtab, &key, av); if (ret) { fprintf(stderr, "Error inserting into avtab\n"); return 1; } } av->data |= 1U << (perm->s.value - 1); return 0; }
int avtab_read(struct avtab *a, void *fp, u32 config) { int i, rc = -EINVAL; struct avtab_key avkey; struct avtab_datum avdatum; u32 *buf; u32 nel; buf = next_entry(fp, sizeof(u32)); if (!buf) { printk(KERN_ERR "security: avtab: truncated table\n"); goto bad; } nel = le32_to_cpu(buf[0]); if (!nel) { printk(KERN_ERR "security: avtab: table is empty\n"); goto bad; } for (i = 0; i < nel; i++) { if (avtab_read_item(fp, &avdatum, &avkey)) goto bad; rc = avtab_insert(a, &avkey, &avdatum); if (rc) { if (rc == -ENOMEM) printk(KERN_ERR "security: avtab: out of memory\n"); if (rc == -EEXIST) printk(KERN_ERR "security: avtab: duplicate entry\n"); goto bad; } } rc = 0; out: return rc; bad: avtab_destroy(a); goto out; }
static int avtab_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *p) { return avtab_insert(a, k, d); }
// Based on public domain code from sepolicy-inject: // https://bitbucket.org/joshua_brindle/sepolicy-inject/ // See the following commit about the hashtab_key_t casts: // https://github.com/TresysTechnology/setools/commit/2994d1ca1da9e6f25f082c0dd1a49b5f958bd2ca bool selinux_add_rule(policydb_t *pdb, const std::string &source_str, const std::string &target_str, const std::string &class_str, const std::string &perm_str) { type_datum_t *source, *target; class_datum_t *clazz; perm_datum_t *perm; avtab_datum_t *av; avtab_key_t key; source = (type_datum_t *) hashtab_search( pdb->p_types.table, (hashtab_key_t) source_str.c_str()); if (!source) { LOGE("Source type %s does not exist", source_str.c_str()); return false; } target = (type_datum_t *) hashtab_search( pdb->p_types.table, (hashtab_key_t) target_str.c_str()); if (!target) { LOGE("Target type %s does not exist", target_str.c_str()); return false; } clazz = (class_datum_t *) hashtab_search( pdb->p_classes.table, (hashtab_key_t) class_str.c_str()); if (!clazz) { LOGE("Class %s does not exist", class_str.c_str()); return false; } perm = (perm_datum_t *) hashtab_search( clazz->permissions.table, (hashtab_key_t) perm_str.c_str()); if (!perm) { if (clazz->comdatum == nullptr) { LOGE("Perm %s does not exist in class %s", perm_str.c_str(), class_str.c_str()); return false; } perm = (perm_datum_t *) hashtab_search( clazz->comdatum->permissions.table, (hashtab_key_t) perm_str.c_str()); if (!perm) { LOGE("Perm %s does not exist in class %s", perm_str.c_str(), class_str.c_str()); return false; } } // See if there is already a rule key.source_type = source->s.value; key.target_type = target->s.value; key.target_class = clazz->s.value; key.specified = AVTAB_ALLOWED; av = avtab_search(&pdb->te_avtab, &key); bool exists = false; if (!av) { avtab_datum_t av_new; av_new.data = (1U << (perm->s.value - 1)); if (avtab_insert(&pdb->te_avtab, &key, &av_new) != 0) { LOGE("Failed to add rule to avtab"); return false; } } else { if (av->data & (1U << (perm->s.value - 1))) { exists = true; } av->data |= (1U << (perm->s.value - 1)); } if (exists) { LOGD("Rule already exists: \"allow %s %s:%s %s;\"", source_str.c_str(), target_str.c_str(), class_str.c_str(), perm_str.c_str()); } else { LOGD("Added rule: \"allow %s %s:%s %s;\"", source_str.c_str(), target_str.c_str(), class_str.c_str(), perm_str.c_str()); } return true; }