RFR: JDK-8289477: Memory corruption caused by CPU_ALLOC, CPU_FREE on muslc

Thomas Stuefe stuefe at openjdk.org
Wed Jun 29 17:19:17 UTC 2022


In `os::Linux::active_processor_count()`, we use the CPU_xxx macros to manage sets of CPU information.

muslc defines those macros to call `calloc(3)` and `free(3)`:


#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
#define CPU_FREE(set) free(set)


whereas glibc uses intermediate functions:


#define __CPU_ALLOC(count) __sched_cpualloc (count)
#define __CPU_FREE(cpuset) __sched_cpufree (cpuset)


which in the end also takes from C-heap, but those calls are not inlined.

So, on muslc we call `calloc()` and `free()`. Call happens inside the `os::Linux` namespace, `free()` resolves to `os::free()`. We have no wrapper in os for calloc though, so `calloc()` calls into muslc right away.

That means we have raw ::malloc() -> os::free(), which is unbalanced. Raw `::malloc()` does not write the header `os::free()` expects. If NMT is on, we assert now, because NMT does not find its header in os::free(). 

This can be very easily reproduced by starting an Alpine VM with NMT on (or, a debug VM) and ` -XX:+UnlockDiagnosticVMOptions -XX:+UseCpuAllocPath`.

The position of the musl devs is that "calloc" and "free" are reserved words in C, and should not be used [1]. I think they are right. The way we reuse known C- and Posix symbol names in the os namespace has bitten me in the past in similar cases.

------

The fix is minimally invasive for easy backporting. I just move the content of `os::Linux::active_processor_count()` into its own local function, outside the os namespace. That way, CPU_FREE cannot pick up `os::free()` accidentally, and the error is fixed.

I really would like a more thorough solution though, renaming all the potential conflict candidates, but leave that for a follow-up RFE.

[1] https://www.openwall.com/lists/musl/2022/06/29/3

-------------

Commit messages:
 - move CPU_xxx calls outside the os:: namespace

Changes: https://git.openjdk.org/jdk/pull/9328/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=9328&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8289477
  Stats: 6 lines in 1 file changed: 5 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/9328.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/9328/head:pull/9328

PR: https://git.openjdk.org/jdk/pull/9328


More information about the hotspot-runtime-dev mailing list