Skip to content

ThreadSanitizer data race in get_page_alignment (sljitUtils.c) during concurrent pcre2_jit_stack_create #924

Description

@zizeca

Description

A data race is detected by ThreadSanitizer (TSan) when multiple threads concurrently invoke pcre2_jit_stack_create_8 for the first time in a process.

While the documentation states that JIT stacks are thread-safe when allocated per-thread, the underlying sljit allocator performs lazy initialization of global/static variables without thread synchronization primitives, leading to Undefined Behavior.

Root Cause

In src/deps/sljit/sljit_src/sljitUtils.c, the function get_page_alignment() initializes a static variable sljit_page_align on its very first call:

static SLJIT_INLINE sljit_uw get_page_alignment(void) {
	static sljit_uw sljit_page_align = 0;

	sljit_sw align;

	if (!sljit_page_align) {
#ifdef _SC_PAGESIZE
		align = sysconf(_SC_PAGESIZE);
#else
		align = getpagesize();
#endif
		/* Should never happen. */
		if (align < 0)
			align = 4096;
		sljit_page_align = (sljit_uw)align - 1;
	}
	return sljit_page_align;
}

If multiple threads concurrently call pcre2_jit_stack_create_8 before page_alignment is initialized, they all enter this block and simultaneously write to the same memory address without a mutex or an atomic store. According to the C11/C++11 memory model, this constitutes a data race.

TSan Stack Trace

Read of size 8 at 0x7fea95cf07a0 by thread T39:
    #0 get_page_alignment pcre2/src/deps/sljit/sljit_src/sljitUtils.c:153
    #1 sljit_allocate_stack pcre2/src/deps/sljit/sljit_src/sljitUtils.c:255
    #2 pcre2_jit_stack_create_8 pcre2/src/pcre2_jit_misc.c:149

Environment

  • PCRE2 Version: 10.46 (and likely reproducible in newer versions as well)
  • Compiler/Toolchain: GCC 13.2.0 / Clang with -fsanitize=thread
  • OS: Linux x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions