Change malloc chunk sizes to be fine grained.
authorotto <otto@openbsd.org>
Sat, 25 Mar 2023 15:22:06 +0000 (15:22 +0000)
committerotto <otto@openbsd.org>
Sat, 25 Mar 2023 15:22:06 +0000 (15:22 +0000)
commitd7c8d7e7923deed51c1a4c7b1e43fc4ecab850d7
tree7144a951a66751c6b28be592c0a34d9633ed4bbc
parent73812c345c6c9bdd17ff30370b22d028b9a89ca9
Change malloc chunk sizes to be fine grained.

The basic idea is simple: one of the reasons the recent sshd bug
is potentially exploitable is that a (erroneously) freed malloc
chunk gets re-used in a different role. malloc has power of two
chunk sizes and so one page of chunks holds many different types
of allocations. Userland malloc has no knowledge of types, we only
know about sizes. So I changed that to use finer-grained chunk
sizes.

This has some performance impact as we need to allocate chunk pages
in more cases. Gain it back by allocation chunk_info pages in a
bundle, and use less buckets is !malloc option S. The chunk sizes
used are 16, 32, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,
384, 448, 512, 640, 768, 896, 1024, 1280, 1536, 1792, 2048 (and a
few more for sparc64 with its 8k sized pages and loongson with its
16k pages).

If malloc option S (or rather cache size 0) is used we use strict
multiple of 16 sized chunks, to get as many buckets as possible.
ssh(d) enabled malloc option S, in general security sensitive
programs should.

See the find_bucket() and bin_of() functions. Thanks to Tony Finch
for pointing me to code to compute nice bucket sizes.

ok tb@
lib/libc/stdlib/malloc.c