When validating a policydb, do a more thorough validation of the constraints. - No permissions if it is a (mls)validatetrans. - Only mlsvalidatetrans can use u3, r3, and t3. - Expressions not involving types should have an empty type set. - Only "==" and "!=" are allowed when there are names. - If names are not used in an expression then both the names bitmap and the type set should be empty. - Only roles and mls expressions can used "dom", "domby", and "incomp". - An mls expression cannot use names. - If the expression is "not", "and", or "or", then the names bitmap and the type set should be empty. Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- libsepol/src/policydb_validate.c | 69 ++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index 735c7a33..2c69f201 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -228,41 +228,69 @@ static int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms constraint_expr_t *cexp; for (; cons; cons = cons->next) { + if (nperms == 0 && cons->permissions != 0) + goto bad; if (nperms > 0 && cons->permissions == 0) goto bad; if (nperms > 0 && nperms != PERM_SYMTAB_SIZE && cons->permissions >= (UINT32_C(1) << nperms)) goto bad; for (cexp = cons->expr; cexp; cexp = cexp->next) { - if (cexp->attr & CEXPR_USER) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS])) - goto bad; - if (validate_empty_type_set(cexp->type_names)) - goto bad; - } else if (cexp->attr & CEXPR_ROLE) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES])) + if (cexp->expr_type == CEXPR_NAMES) { + if (cexp->attr & CEXPR_XTARGET && nperms != 0) goto bad; - if (validate_empty_type_set(cexp->type_names)) - goto bad; - } else if (cexp->attr & CEXPR_TYPE) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES])) + if (!(cexp->attr & CEXPR_TYPE)) { + if (validate_empty_type_set(cexp->type_names)) + goto bad; + } + + switch (cexp->op) { + case CEXPR_EQ: + case CEXPR_NEQ: + break; + default: goto bad; - if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES])) + } + + switch (cexp->attr) { + case CEXPR_USER: + case CEXPR_USER | CEXPR_TARGET: + case CEXPR_USER | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS])) + goto bad; + break; + case CEXPR_ROLE: + case CEXPR_ROLE | CEXPR_TARGET: + case CEXPR_ROLE | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES])) + goto bad; + break; + case CEXPR_TYPE: + case CEXPR_TYPE | CEXPR_TARGET: + case CEXPR_TYPE | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES])) + goto bad; + if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES])) + goto bad; + break; + default: goto bad; - } else { + } + } else if (cexp->expr_type == CEXPR_ATTR) { if (!ebitmap_is_empty(&cexp->names)) goto bad; if (validate_empty_type_set(cexp->type_names)) goto bad; - } - if (cexp->expr_type == CEXPR_ATTR || cexp->expr_type == CEXPR_NAMES) { switch (cexp->op) { case CEXPR_EQ: case CEXPR_NEQ: + break; case CEXPR_DOM: case CEXPR_DOMBY: case CEXPR_INCOMP: + if ((cexp->attr & CEXPR_USER) || (cexp->attr & CEXPR_TYPE)) + goto bad; break; default: goto bad; @@ -270,14 +298,8 @@ static int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms switch (cexp->attr) { case CEXPR_USER: - case CEXPR_USER | CEXPR_TARGET: - case CEXPR_USER | CEXPR_XTARGET: case CEXPR_ROLE: - case CEXPR_ROLE | CEXPR_TARGET: - case CEXPR_ROLE | CEXPR_XTARGET: case CEXPR_TYPE: - case CEXPR_TYPE | CEXPR_TARGET: - case CEXPR_TYPE | CEXPR_XTARGET: case CEXPR_L1L2: case CEXPR_L1H2: case CEXPR_H1L2: @@ -300,9 +322,12 @@ static int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms if (cexp->op != 0) goto bad; - if (cexp->attr != 0) goto bad; + if (!ebitmap_is_empty(&cexp->names)) + goto bad; + if (validate_empty_type_set(cexp->type_names)) + goto bad; } } } -- 2.34.1