diff mbox series

libsepol: Do a more thorough validation of constraints

Message ID 20220303214750.566685-1-jwcart2@gmail.com (mailing list archive)
State Accepted
Commit 5b6e6254b572
Headers show
Series libsepol: Do a more thorough validation of constraints | expand

Commit Message

James Carter March 3, 2022, 9:47 p.m. UTC
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@gmail.com>
---
 libsepol/src/policydb_validate.c | 69 ++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 22 deletions(-)

Comments

James Carter March 11, 2022, 4:03 p.m. UTC | #1
On Thu, Mar 3, 2022 at 4:48 PM James Carter <jwcart2@gmail.com> wrote:
>
> 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@gmail.com>

This has been merged.
Jim

> ---
>  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
>
diff mbox series

Patch

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;
 			}
 		}
 	}