From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <5587FC35.4040300@tresys.com> Date: Mon, 22 Jun 2015 08:14:45 -0400 From: Steve Lawrence MIME-Version: 1.0 To: James Carter , Subject: Re: [PATCH 08/10 v3] libsepol/cil: Add CIL bounds checking and reporting. References: <1434737956-17932-1-git-send-email-jwcart2@tycho.nsa.gov> <1434737956-17932-9-git-send-email-jwcart2@tycho.nsa.gov> In-Reply-To: <1434737956-17932-9-git-send-email-jwcart2@tycho.nsa.gov> Content-Type: text/plain; charset="windows-1252" List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: On 06/19/2015 02:19 PM, James Carter wrote: > Use the libsepol bounds checking to check for and report user and > role bounds violations. > > For type bounds checking, use libsepol bounds checking to determine > if there is a violation for a given type. For each violation display > an error message that includes the CIL AST from the root node to the > node of the rule causing the violation. > > Example error report: > Child type b_t3_c exceeds bounds of parent b_t3 > (allow b_t3_c b_tc (file (write))) > > booleanif at line 148633 of cil.conf.bounds > true at line 148634 of cil.conf.bounds > allow at line 148636 of cil.conf.bounds > (allow b_t3_c b_tc (file (read write))) > > Signed-off-by: James Carter Acked-by: Steve Lawrence > --- > libsepol/cil/src/cil_binary.c | 135 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 135 insertions(+) > > diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c > index 066184a..6d095db 100644 > --- a/libsepol/cil/src/cil_binary.c > +++ b/libsepol/cil/src/cil_binary.c > @@ -3903,6 +3903,130 @@ exit: > return rc; > } > > +static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) > +{ > + struct cil_classperms *cp; > + struct cil_list *cp_list; > + class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1]; > + unsigned i; > + > + cil_classperms_init(&cp); > + > + cp->class = class_value_to_cil[class]; > + if (!cp->class) goto exit; > + > + cil_list_init(&cp->perms, CIL_PERM); > + for (i = 0; i < sepol_class->permissions.nprim; i++) { > + struct cil_perm *perm; > + if ((data & (1 << i)) == 0) continue; > + perm = perm_value_to_cil[class][i+1]; > + if (!perm) goto exit; > + cil_list_append(cp->perms, CIL_PERM, perm); > + } > + > + cil_list_init(&cp_list, CIL_CLASSPERMS); > + cil_list_append(cp_list, CIL_CLASSPERMS, cp); > + > + return cp_list; > + > +exit: > + cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n"); > + return NULL; > +} > + > +static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) > +{ > + int rc = SEPOL_ERR; > + avtab_key_t *k = &sepol_rule->key; > + avtab_datum_t *d = &sepol_rule->datum; > + cil_rule->src = type_value_to_cil[k->source_type]; > + if (!cil_rule->src) goto exit; > + > + cil_rule->tgt = type_value_to_cil[k->target_type]; > + if (!cil_rule->tgt) goto exit; > + > + cil_rule->classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil); > + if (!cil_rule->classperms) goto exit; > + > + return SEPOL_OK; > + > +exit: > + cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n"); > + return rc; > +} > + > +static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) > +{ > + int rc = SEPOL_OK; > + int i; > + > + for (i = 0; i < db->num_types; i++) { > + type_datum_t *child; > + type_datum_t *parent; > + avtab_ptr_t bad = NULL; > + int numbad = 0; > + struct cil_type *t = db->val_to_type[i]; > + > + if (!t->bounds) continue; > + > + rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child); > + if (rc != SEPOL_OK) goto exit; > + > + rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent); > + if (rc != SEPOL_OK) goto exit; > + > + rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad); > + if (rc != SEPOL_OK) goto exit; > + > + if (bad) { > + avtab_ptr_t cur; > + struct cil_avrule target; > + > + target.rule_kind = CIL_AVRULE_ALLOWED; > + target.src_str = NULL; > + target.tgt_str = NULL; > + > + cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n", > + t->datum.fqn, t->bounds->datum.fqn); > + for (cur = bad; cur; cur = cur->next) { > + struct cil_list_item *i2; > + struct cil_list *matching; > + struct cil_tree_node *n; > + > + rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil); > + if (rc != SEPOL_OK) { > + cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n"); > + goto exit; > + } > + __cil_print_rule(" ", "allow", &target); > + cil_list_init(&matching, CIL_NODE); > + rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE); > + if (rc) { > + cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); > + cil_list_destroy(&matching, CIL_FALSE); > + cil_list_destroy(&target.classperms, CIL_TRUE); > + bounds_destroy_bad(bad); > + goto exit; > + } > + > + cil_list_for_each(i2, matching) { > + __cil_print_parents(" ", (struct cil_tree_node *)i2->data); > + } > + i2 = matching->tail; > + n = i2->data; > + __cil_print_rule(" ", "allow", n->data); > + cil_log(CIL_ERR,"\n"); > + cil_list_destroy(&matching, CIL_FALSE); > + cil_list_destroy(&target.classperms, CIL_TRUE); > + } > + bounds_destroy_bad(bad); > + } > + } > + > +exit: > + return rc; > +} > + > // assumes policydb is already allocated and initialized properly with things > // like policy type set to kernel and version set appropriately > int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb) > @@ -4022,6 +4146,17 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p > cil_log(CIL_INFO, "Checking Neverallows\n"); > rc = cil_check_neverallows(db, pdb, neverallows); > if (rc != SEPOL_OK) goto exit; > + > + cil_log(CIL_INFO, "Checking User Bounds\n"); > + bounds_check_users(NULL, pdb); > + > + cil_log(CIL_INFO, "Checking Role Bounds\n"); > + bounds_check_roles(NULL, pdb); > + > + cil_log(CIL_INFO, "Checking Type Bounds\n"); > + rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil); > + if (rc != SEPOL_OK) goto exit; > + > } > > rc = SEPOL_OK; >