Skip to content

Align storage for the memory_map singleton - #298

Merged
emeryberger merged 1 commit into
plasma-umass:masterfrom
zeph1912:master
Oct 26, 2026
Merged

emeryberger merged 1 commit into
plasma-umass:masterfrom
zeph1912:master

Conversation

@zeph1912

Copy link
Copy Markdown
Contributor

memory_map::get_instance() constructs a memory_map in a function-local
static char array. The declaration does not guarantee alignof(memory_map)
(eight bytes in the tested AArch64 build), so placement construction can use
under-aligned storage and cause undefined behavior.

Add alignas(memory_map) to the buffer, matching the profiler singleton fix
in #288 (acd0081).

Reproducer and observed failure

Tested on Linux AArch64, Ubuntu 24.04, Clang 18.1.3, on commit
256e3c389424d6a1691ee5d18b5ecb5a6c1001ec.

Save this as memory-map-poc.cpp in the Coz checkout. It uses the real
memory_map definition from inspect.h and copies the original getter.
The preceding one-byte global deliberately perturbs the storage layout to
expose the missing alignment requirement.

#include "inspect.h"

// Perturb the layout to expose the buffer's missing alignment guarantee.
alignas(memory_map) volatile char layout_prefix;

memory_map& memory_map::get_instance() {
  static char buf[sizeof(memory_map)];
  static memory_map* the_instance = new(buf) memory_map();
  return *the_instance;
}

int main() {
  layout_prefix = 1;
  (void)memory_map::get_instance();
}

Compile and run:

clang++ -std=c++11 -O0 -g \
  -fsanitize=alignment -fno-sanitize-recover=alignment \
  -Ilibcoz memory-map-poc.cpp -o memory-map-poc
./memory-map-poc

UBSan crash:

/trial/coz/libcoz/inspect.h:157:3: runtime error: constructor call on misaligned address 0xaaaab53844f9 for type 'memory_map *', which requires 8 byte alignment
0xaaaab53844f9: note: pointer points here
 00 00 00  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00
              ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /trial/coz/libcoz/inspect.h:157:3

After this patch, which changes the buffer declaration to
alignas(memory_map) static char buf[sizeof(memory_map)]; the same test
exit with status 0 and no sanitizer crash. The failure depends on specific compiler
layout: GCC 13.3 happened to align the buffer in the earlier test.

Verification

Tested on Clang 18.1.3 RelWithDebInfo build, C++11.
The integration tests were run with:

ctest --test-dir build-clang --output-on-failure \
  -R '^(path_filter|dwarf_scope_filter)$'
Check Before After
The alignment bug reproducer Misaligned constructor UBSan crash No crash
Clang build Pass Pass
path_filter Pass Pass
dwarf_scope_filter with DWARF 5 Pass Pass

`memory_map::get_instance()` constructs a `memory_map` in a function-local
`static char` array. That declaration does not guarantee the alignment
required by `memory_map`, so placement construction can use under-aligned
storage and cause undefined behavior.

Add `alignas(memory_map)` to the buffer, matching the profiler singleton
fix in acd0081.
@emeryberger
emeryberger marked this pull request as ready for review October 26, 2026 22:12
@emeryberger emeryberger reopened this Oct 26, 2026
@emeryberger emeryberger reopened this Oct 26, 2026
@emeryberger
emeryberger merged commit dfc22c6 into plasma-umass:master Oct 26, 2026
28 of 30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants