#3471·seastar

memory: large aligned allocations can return under-aligned pointers

Author: dkropachevCreated Jun 20, 2026Updated Sep 16, 2026
Labelsai-assisted

Summary

The Seastar allocator's large aligned allocation path computes the requested alignment in pages, but the lower-level allocator ignores that value. As a result, valid aligned allocation requests whose alignment is larger than the requested size can return a pointer that is only aligned to the allocated buddy span size, not to the requested alignment.

For example, on the default 4 KiB allocator page size, a reactor-thread call like:

cpp
void* p = nullptr;
int rc = posix_memalign(&p, 2 << 20, 4096);

can succeed with p only 4 KiB-aligned instead of 2 MiB-aligned. That violates the posix_memalign() alignment contract.

Code path

Current origin/master has this flow:

  • posix_memalign() calls allocate_aligned(align, size).
  • allocate_aligned() routes requests with align > page_size through allocate_large_aligned(align, size), even when size <= max_small_allocation.
  • allocate_large_aligned(size_t align, size_t size, ...) computes align_in_pages and passes it down.
  • cpu_pages::allocate_large_aligned(unsigned align_pages, unsigned n_pages, ...) ignores align_pages and delegates directly to allocate_large_and_trim(n_pages, ...) with the comment // buddy allocation is always aligned.
  • allocate_large_and_trim() selects a suitable buddy span, trims it down to the requested n_pages, and returns mem() + span_idx * page_size.

Buddy allocation only guarantees natural alignment to the span size that is actually allocated. If n_pages == 1, the returned pointer is only guaranteed to be one allocator page aligned. It is not guaranteed to satisfy a larger requested alignment such as 512 pages / 2 MiB.

Why this matters

This is reachable through public aligned allocation entry points on reactor threads, including:

  • posix_memalign()
  • memalign()
  • aligned_alloc()
  • aligned C++ operator new(size_t, std::align_val_t)

Existing allocator tests cover cases where size >= align up to 64 KiB, but they do not cover the valid case where align > size, such as posix_memalign(&p, 2 MiB, 4 KiB).

Expected behavior

Large aligned allocations should either return a pointer aligned to the requested alignment or fail. For requests where align_pages > n_pages, the allocator likely needs to allocate/search a span large enough to contain an aligned subspan, return the aligned portion, and free the unused prefix/suffix appropriately.

Related: #3467 also touches allocate_large_aligned(), but it is about page-count overflow/truncation. This issue is about the requested alignment being ignored after conversion to pages.