Re: selinux:selabel_file_text-fuzzer: Null-dereference READ in selabel_file_text-fuzzer

Stephen Smalley <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ6-b4KmkgSgO7hXf+8ZGgRtR_JkS1ZQU-ULVk0aex5zCw@mail.gmail.com>
On Wed, Aug 19, 2026 at 2:26 PM Stephen Smalley
<[email protected]> wrote:
>
> On Wed, Aug 19, 2026 at 2:18 PM Stephen Smalley
> <[email protected]> wrote:
> >
> > This is oss-fuzz issue 547975134. Crash stacktrace below and
> > reproducer attached.
>
> Here is a more useful stack trace along with the fuzzer input header
> information decoded (\s is a whitespace character of some form):
> find_all
> mode
> fcontext_data_len=16 fcontext=(|(?0(1)))++c|\s?
> len=1 key=\s
> *** stack smashing detected ***: terminated
> ==4287==
> ==4287== Process terminating with default action of signal 6
> (SIGABRT): dumping core
> ==4287==    at 0x48E3CCC: __pthread_kill_implementation (pthread_kill.c:44)
> ==4287==    by 0x4888E8D: raise (raise.c:26)
> ==4287==    by 0x48707B2: abort (abort.c:77)
> ==4287==    by 0x4871803: __libc_message_impl.cold (libc_fatal.c:138)
> ==4287==    by 0x4970F8F: __libc_message_wrapper (stdio.h:203)
> ==4287==    by 0x4970F8F: __fortify_fail (fortify_fail.c:24)
> ==4287==    by 0x4972343: __stack_chk_fail (stack_chk_fail.c:24)
> ==4287==    by 0x42E1BA: jit_machine_stack_exec (pcre2_jit_match_inc.h:64)
> ==4287==    by 0x46772F: pcre2_jit_match_8 (pcre2_jit_match_inc.h:173)
> ==4287==    by 0x47D034: pcre2_match_8 (pcre2_match.c:7204)
> ==4287==    by 0x40FA51: regex_match (regex.c:295)
> ==4287==    by 0x409D52: lookup_check_node (label_file.c:2013)
> ==4287==    by 0x40A4FA: lookup_all (label_file.c:2278)

To clarify, the \s above is a single space character in both the regex
and the key.
My decoder for the fuzzing input just prints it as \s.

My friendly neighborhood AI suggests that the pattern (|(?0(1)))++c| ?
triggers a stack overflow on a single space because it creates a
catastrophic combination of possessive quantifiers, zero-length
matches, and infinite recursion. Standard interpreted PCRE2 tracks
recursion depth and will gracefully abort with a
PCRE2_ERROR_MATCHLIMIT or PCRE2_ERROR_DEPTHLIMIT. However, the JIT
compiler generates optimized native machine code that relies on a
dedicated, fixed-size memory stack for its execution. Because this
zero-length infinite recursion rapidly cascades without consuming any
input, it instantly exhausts the JIT's memory block, resulting in a
fatal stack overflow (or a PCRE2_ERROR_JIT_STACKLIMIT crash depending
on your environment).

It suggests doing one of the following:
1. Bounded Limits: Ensure libselinux sets strict match limits and
bounds the JIT stack size explicitly using pcre2_jit_stack_create.
-or-
2. Fuzzer Fallbacks: Maintainers sometimes conditionally disable JIT
compilation inside the fuzzer harness itself. This forces PCRE2 to use
its interpreter, which gracefully handles the recursion limit and
returns a PCRE2_ERROR_DEPTHLIMIT rather than crashing the process.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.