diff mbox series

[2/2] libsepol: Check kernel to CIL and Conf functions for supported versions

Message ID 20210311154105.195494-2-jwcart2@gmail.com (mailing list archive)
State Superseded
Headers show
Series [1/2] checkpolicy: Do not automatically upgrade when using "-b" flag | expand

Commit Message

James Carter March 11, 2021, 3:41 p.m. UTC
For policy versions between 20 and 23, attributes exist in the
policy, but only in the type_attr_map. This means that there are
gaps in both the type_val_to_struct and p_type_val_to_name arrays
and policy rules can refer to those gaps which can lead to NULL
dereferences when using sepol_kernel_policydb_to_conf() and
sepol_kernel_policydb_to_cil().

This can be seen with the following policy:
  class CLASS1
  sid SID1
  class CLASS1 { PERM1 }
  attribute TYPE_ATTR1;
  type TYPE1;
  typeattribute TYPE1 TYPE_ATTR1;
  allow TYPE_ATTR1 self : CLASS1 PERM1;
  role ROLE1;
  role ROLE1 types TYPE1;
  user USER1 roles ROLE1;
  sid SID1 USER1:ROLE1:TYPE1

Compile the policy:
  checkpolicy -c 23 -o policy.bin policy.conf
Converting back to a policy.conf causes a segfault:
  checkpolicy -F -b -o policy.bin.conf policy.bin

Have both sepol_kernel_policydb_to_conf() and
sepol_kernel_policydb_to_cil() exit with an error if the kernel
policy version is between 20 and 23.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/src/kernel_to_cil.c  | 12 ++++++++++++
 libsepol/src/kernel_to_conf.c | 12 ++++++++++++
 2 files changed, 24 insertions(+)

Comments

Nicolas Iooss March 14, 2021, 7:53 p.m. UTC | #1
On Thu, Mar 11, 2021 at 4:41 PM James Carter <jwcart2@gmail.com> wrote:
>
> For policy versions between 20 and 23, attributes exist in the
> policy, but only in the type_attr_map. This means that there are
> gaps in both the type_val_to_struct and p_type_val_to_name arrays
> and policy rules can refer to those gaps which can lead to NULL
> dereferences when using sepol_kernel_policydb_to_conf() and
> sepol_kernel_policydb_to_cil().
>
> This can be seen with the following policy:
>   class CLASS1
>   sid SID1
>   class CLASS1 { PERM1 }
>   attribute TYPE_ATTR1;
>   type TYPE1;
>   typeattribute TYPE1 TYPE_ATTR1;
>   allow TYPE_ATTR1 self : CLASS1 PERM1;
>   role ROLE1;
>   role ROLE1 types TYPE1;
>   user USER1 roles ROLE1;
>   sid SID1 USER1:ROLE1:TYPE1
>
> Compile the policy:
>   checkpolicy -c 23 -o policy.bin policy.conf
> Converting back to a policy.conf causes a segfault:
>   checkpolicy -F -b -o policy.bin.conf policy.bin
>
> Have both sepol_kernel_policydb_to_conf() and
> sepol_kernel_policydb_to_cil() exit with an error if the kernel
> policy version is between 20 and 23.
>
> Signed-off-by: James Carter <jwcart2@gmail.com>

For this patch: Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>

(for the first one, I reported a regression in "checkpolicy -V")

Thanks,
Nicolas

> ---
>  libsepol/src/kernel_to_cil.c  | 12 ++++++++++++
>  libsepol/src/kernel_to_conf.c | 12 ++++++++++++
>  2 files changed, 24 insertions(+)
>
> diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
> index a146ac51..edfebeaf 100644
> --- a/libsepol/src/kernel_to_cil.c
> +++ b/libsepol/src/kernel_to_cil.c
> @@ -3164,6 +3164,18 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb)
>                 goto exit;
>         }
>
> +       if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
> +               /*
> +                * For policy versions between 20 and 23, attributes exist in the policy,
> +                * but only in the type_attr_map. This means that there are gaps in both
> +                * the type_val_to_struct and p_type_val_to_name arrays and policy rules
> +                * can refer to those gaps.
> +                */
> +               sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported");
> +               rc = -1;
> +               goto exit;
> +       }
> +
>         rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
>         if (rc != 0) {
>                 goto exit;
> diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
> index a22f196d..ea58a026 100644
> --- a/libsepol/src/kernel_to_conf.c
> +++ b/libsepol/src/kernel_to_conf.c
> @@ -3041,6 +3041,18 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb)
>                 goto exit;
>         }
>
> +       if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
> +               /*
> +                * For policy versions between 20 and 23, attributes exist in the policy,
> +                * but only in the type_attr_map. This means that there are gaps in both
> +                * the type_val_to_struct and p_type_val_to_name arrays and policy rules
> +                * can refer to those gaps.
> +                */
> +               sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported");
> +               rc = -1;
> +               goto exit;
> +       }
> +
>         rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
>         if (rc != 0) {
>                 goto exit;
> --
> 2.26.2
>
diff mbox series

Patch

diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index a146ac51..edfebeaf 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -3164,6 +3164,18 @@  int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb)
 		goto exit;
 	}
 
+	if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
+		/*
+		 * For policy versions between 20 and 23, attributes exist in the policy,
+		 * but only in the type_attr_map. This means that there are gaps in both
+		 * the type_val_to_struct and p_type_val_to_name arrays and policy rules
+		 * can refer to those gaps.
+		 */
+		sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported");
+		rc = -1;
+		goto exit;
+	}
+
 	rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
 	if (rc != 0) {
 		goto exit;
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
index a22f196d..ea58a026 100644
--- a/libsepol/src/kernel_to_conf.c
+++ b/libsepol/src/kernel_to_conf.c
@@ -3041,6 +3041,18 @@  int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb)
 		goto exit;
 	}
 
+	if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) {
+		/*
+		 * For policy versions between 20 and 23, attributes exist in the policy,
+		 * but only in the type_attr_map. This means that there are gaps in both
+		 * the type_val_to_struct and p_type_val_to_name arrays and policy rules
+		 * can refer to those gaps.
+		 */
+		sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported");
+		rc = -1;
+		goto exit;
+	}
+
 	rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints);
 	if (rc != 0) {
 		goto exit;