Re: [PATCH v2] libsepol: add module package fuzzer

Stephen Smalley <[email protected]> Tue, 21 Jul 2026 15:41:57 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ7Bg8FV12YqHxOzHr+Z3za6M1hoCOV_OL68PJ1Jf23G+A@mail.gmail.com>
On Tue, Jul 21, 2026 at 7:16 AM Petr Matyas <[email protected]> wrote:
>
> Add a libFuzzer target for the binary module package format
> (.mod/.pp) read by sepol_module_package_read(). On a valid package,
> also exercises sepol_module_package_to_cil() to cover the CIL
> conversion path for module policies.
>
> The seed corpus contains a minimal module package produced by
> checkmodule + semodule_package to give the fuzzer a structurally
> correct starting point.
>
> Wire the new fuzzer into scripts/oss-fuzz.sh alongside the existing
> libsepol and checkpolicy fuzzers.
>
> Signed-off-by: Petr Matyas <[email protected]>

Acked-by: Stephen Smalley <[email protected]>

> ---
>  libsepol/fuzz/min_mod.pp              | Bin 0 -> 859 bytes
>  libsepol/fuzz/module-package-fuzzer.c |  47 ++++++++++++++++++++++++++
>  scripts/oss-fuzz.sh                   |  11 ++++++
>  3 files changed, 58 insertions(+)
>  create mode 100644 libsepol/fuzz/min_mod.pp
>  create mode 100644 libsepol/fuzz/module-package-fuzzer.c
>
> diff --git a/libsepol/fuzz/min_mod.pp b/libsepol/fuzz/min_mod.pp
> new file mode 100644
> index 0000000000000000000000000000000000000000..264bd4406bf94b1c0044d46d0ca82fcdc4716f88
> GIT binary patch
> literal 859
> zcmb`FOA5k35Jbxl=uVd|J%Q*A+_=+~2MCyq;4dTjfQwu~Jg+OIFa^zEK*a~mbWhh*
> zC(yS?b#DP+3;|pp)qMb9y%;ZdX?Yp1d{Q1=8^EZR_3@$y;IvDllTSJTW|Qf>?pS0_
> zHBrrzoHHN0Jnz=6t<MgUaFAqvvv+Y3Wp+eUE^I&aR86ez;Ih;mqe31{=)Jy=*gJYM
> z)YoZe5nJ0l^b4_C<_yiy`HMz`Zw0+SohO>SzP<k!{0FXMy?QKdaP72i-21Sn6|wj4
> Fcmk%9EE)g+
>
> literal 0
> HcmV?d00001
>
> diff --git a/libsepol/fuzz/module-package-fuzzer.c b/libsepol/fuzz/module-package-fuzzer.c
> new file mode 100644
> index 00000000..2516970b
> --- /dev/null
> +++ b/libsepol/fuzz/module-package-fuzzer.c
> @@ -0,0 +1,47 @@
> +#include <sepol/debug.h>
> +#include <sepol/module.h>
> +#include <sepol/module_to_cil.h>
> +
> +extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
> +
> +// set to 1 to enable more verbose libsepol logging
> +#define VERBOSE 0
> +
> +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
> +{
> +       sepol_module_package_t *mod = NULL;
> +       struct sepol_policy_file *spf = NULL;
> +       FILE *devnull = NULL;
> +
> +       sepol_debug(VERBOSE);
> +
> +       if (sepol_policy_file_create(&spf))
> +               goto exit;
> +
> +       sepol_policy_file_set_mem(spf, (char *)data, size);
> +
> +       if (sepol_module_package_create(&mod))
> +               goto exit;
> +
> +       if (sepol_module_package_read(mod, spf, VERBOSE))
> +               goto exit;
> +
> +       devnull = fopen("/dev/null", "we");
> +       if (!devnull)
> +               goto exit;
> +
> +       /* sepol_module_package_read() stores contexts sections as raw blobs
> +        * without validating their text syntax; sepol_module_package_to_cil()
> +        * is the first place that parses them, so a graceful error return here
> +        * is expected behaviour for malformed input, not a bug. */
> +       (void)sepol_module_package_to_cil(devnull, mod);
> +
> +exit:
> +       if (devnull)
> +               fclose(devnull);
> +       sepol_module_package_free(mod);
> +       sepol_policy_file_free(spf);
> +
> +       /* Non-zero return values are reserved for future use. */
> +       return 0;
> +}
> diff --git a/scripts/oss-fuzz.sh b/scripts/oss-fuzz.sh
> index 9376b6e4..08e06975 100755
> --- a/scripts/oss-fuzz.sh
> +++ b/scripts/oss-fuzz.sh
> @@ -74,6 +74,17 @@ $CXX $CXXFLAGS $LIB_FUZZING_ENGINE binpolicy-fuzzer.o "$DESTDIR/usr/lib/libsepol
>
>  zip -j "$OUT/binpolicy-fuzzer_seed_corpus.zip" libsepol/fuzz/policy.bin
>
> +## module package fuzzer ##
> +
> +# CFLAGS, CXXFLAGS and LIB_FUZZING_ENGINE have to be split to be accepted by
> +# the compiler/linker so they shouldn't be quoted
> +# shellcheck disable=SC2086
> +$CC $CFLAGS -c -o module-package-fuzzer.o libsepol/fuzz/module-package-fuzzer.c
> +# shellcheck disable=SC2086
> +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE module-package-fuzzer.o "$DESTDIR/usr/lib/libsepol.a" -o "$OUT/module-package-fuzzer"
> +
> +zip -j "$OUT/module-package-fuzzer_seed_corpus.zip" libsepol/fuzz/min_mod.pp
> +
>  ## checkpolicy fuzzer ##
>
>  make -C checkpolicy clean
> --
> 2.55.0
>
>