summaryrefslogtreecommitdiff
path: root/src/malloc/mallocng/meta.h
AgeCommit message (Collapse)AuthorLines
2026-05-12mallocng: fix handling of allocations with extreme alignmentRich Felker-1/+2
aligned allocations are handled by over-allocating enough to ensure an aligned subrange exists and framing the usable space to that subrange. the framing can only handle offsets up to a 32-bit multiple of the allocation UNIT (16 bytes), and aligned_alloc correctly checks for and rejects larger alignments. however, when get_meta reads back the offset, the type of the variable and everything else in the expression where it's used was int, not size_t, and offset*UNIT can overflow. modulo the "anything can happen" aspect of overflow being undefined, a clean trap will occur and the program will terminate. this would happen on any call to free, realloc, or malloc_usable_size call on the large-alignment object. switch the type of offset in get_meta from int to size_t. this has been checked not to break any of the subsequent assertions: - assert(offset > 0xffff) was wrongly rejecting offsets that would be interpreted as negative when converted to signed int. this is fixed by processing offset as unsigned. - the check against the slot boundaries switches which assert would catch values that were previously interpreted as negative, but the net effect is the same. - the check against maplen was already converting to unsigned long due to the 4096UL in the expression. in doing so, it was incorrectly sign-extending the offset rather than zero-extending. this is fixed by using unsigned type to begin with. in addition, take the opportunity to trap on offsets were offset*UNIT would overflow. this cannot happen on 64-bit archs (and it should be optimized out by the compiler there), but it's an additional signal we can use to catch out-of-bounds writes on 32-bit ones. and the check only happens when operating on extremely large, overaligned objects, so the relative cost of checking is essentially zero.
2020-06-30import mallocngRich Felker-0/+288
the files added come from the mallocng development repo, commit 2ed58817cca5bc055974e5a0e43c280d106e696b. they comprise a new malloc implementation, developed over the past 9 months, to replace the old allocator (since dubbed "oldmalloc") with one that retains low code size and minimal baseline memory overhead while avoiding fundamental flaws in oldmalloc and making significant enhancements. these include highly controlled fragmentation, fine-grained ability to return memory to the system when freed, and strong hardening against dynamic memory usage errors by the caller. internally, mallocng derives most of these properties from tightly structuring memory, creating space for allocations as uniform-sized slots within individually mmapped (and individually freeable) allocation groups. smaller-than-pagesize groups are created within slots of larger ones. minimal group size is very small, and larger sizes (in geometric progression) only come into play when usage is high. all data necessary for maintaining consistency of the allocator state is tracked in out-of-band metadata, reachable via a validated path from minimal in-band metadata. all pointers passed (to free, etc.) are validated before any stores to memory take place. early reuse of freed slots is avoided via approximate LRU order of freed slots. further hardening against use-after-free and double-free, even in the case where the freed slot has been reused, is made by cycling the offset within the slot at which the allocation is placed; this is possible whenever the slot size is larger than the requested allocation.