diff mbox series

libsepol: ignore writing invalid polcaps in fuzzer

Message ID 20231101163852.177983-1-cgzones@googlemail.com (mailing list archive)
State New, archived
Delegated to: Petr Lautrbach
Headers show
Series libsepol: ignore writing invalid polcaps in fuzzer | expand

Commit Message

Christian Göttsche Nov. 1, 2023, 4:38 p.m. UTC
Kernel policies with unsupported policy capabilities enabled can
currently be parsed, since they result just in a bit set inside an
ebitmap.  Writing such a loaded policy into the traditional language or
CIL will fail however, since unsupported policy capabilities can not
be converted into names.

This currently affects the fuzzer, since it generates such policies and
then fails to write them.

Ignore writing invalid policy capabilities only for the fuzzer.  Thus
users can still use old libsepol versions to analyze (but not write)
policies with new policy capabilities, since capabilities can be
introduced without a new policy version.

Reported-by: oss-fuzz (issue 60573)

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libsepol/src/kernel_to_cil.c  | 4 ++++
 libsepol/src/kernel_to_conf.c | 4 ++++
 2 files changed, 8 insertions(+)

Comments

James Carter Nov. 2, 2023, 8:04 p.m. UTC | #1
On Wed, Nov 1, 2023 at 12:39 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> Kernel policies with unsupported policy capabilities enabled can
> currently be parsed, since they result just in a bit set inside an
> ebitmap.  Writing such a loaded policy into the traditional language or
> CIL will fail however, since unsupported policy capabilities can not
> be converted into names.
>
> This currently affects the fuzzer, since it generates such policies and
> then fails to write them.
>
> Ignore writing invalid policy capabilities only for the fuzzer.  Thus
> users can still use old libsepol versions to analyze (but not write)
> policies with new policy capabilities, since capabilities can be
> introduced without a new policy version.
>
> Reported-by: oss-fuzz (issue 60573)
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  libsepol/src/kernel_to_cil.c  | 4 ++++
>  libsepol/src/kernel_to_conf.c | 4 ++++
>  2 files changed, 8 insertions(+)
>
> diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
> index 8fcc385d..f94d67f5 100644
> --- a/libsepol/src/kernel_to_cil.c
> +++ b/libsepol/src/kernel_to_cil.c
> @@ -1198,9 +1198,13 @@ static int write_polcap_rules_to_cil(FILE *out, struct policydb *pdb)
>         ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) {
>                 name = sepol_polcap_getname(i);
>                 if (name == NULL) {
> +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
> +                       continue;
> +#else
>                         ERR(NULL, "Unknown policy capability id: %i", i);
>                         rc = -1;
>                         goto exit;
> +#endif
>                 }
>
>                 rc = strs_create_and_add(strs, "(policycap %s)", 1, name);
> diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
> index b0ae16d9..a752667c 100644
> --- a/libsepol/src/kernel_to_conf.c
> +++ b/libsepol/src/kernel_to_conf.c
> @@ -1181,9 +1181,13 @@ static int write_polcap_rules_to_conf(FILE *out, struct policydb *pdb)
>         ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) {
>                 name = sepol_polcap_getname(i);
>                 if (name == NULL) {
> +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
> +                       continue;
> +#else
>                         ERR(NULL, "Unknown policy capability id: %i", i);
>                         rc = -1;
>                         goto exit;
> +#endif
>                 }
>
>                 rc = strs_create_and_add(strs, "policycap %s;", 1, name);
> --
> 2.42.0
>

I don't understand this patch. The fuzzer is generating an invalid
policy, so, of course, there is an error. The kernel has to be
conservative because an older kernel might have to deal with a policy
generated by a newer userspace. We do not guarantee that an older
userspace can handle a new policy. Nothing in the userspace allows
invalid policy capabilities. These two functions are following the
example of checkpolicy and secilc and giving an error for an invalid
policy capability. I am not going to make an exception for the fuzzer.
Jim
diff mbox series

Patch

diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
index 8fcc385d..f94d67f5 100644
--- a/libsepol/src/kernel_to_cil.c
+++ b/libsepol/src/kernel_to_cil.c
@@ -1198,9 +1198,13 @@  static int write_polcap_rules_to_cil(FILE *out, struct policydb *pdb)
 	ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) {
 		name = sepol_polcap_getname(i);
 		if (name == NULL) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+			continue;
+#else
 			ERR(NULL, "Unknown policy capability id: %i", i);
 			rc = -1;
 			goto exit;
+#endif
 		}
 
 		rc = strs_create_and_add(strs, "(policycap %s)", 1, name);
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
index b0ae16d9..a752667c 100644
--- a/libsepol/src/kernel_to_conf.c
+++ b/libsepol/src/kernel_to_conf.c
@@ -1181,9 +1181,13 @@  static int write_polcap_rules_to_conf(FILE *out, struct policydb *pdb)
 	ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) {
 		name = sepol_polcap_getname(i);
 		if (name == NULL) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+			continue;
+#else
 			ERR(NULL, "Unknown policy capability id: %i", i);
 			rc = -1;
 			goto exit;
+#endif
 		}
 
 		rc = strs_create_and_add(strs, "policycap %s;", 1, name);