fix u16 truncation in slab random quarantine indexing#329
Open
thomasbuilds wants to merge 1 commit into
Open
Conversation
Member
|
This shouldn't use |
slab_quarantine_random_length = SLAB_QUARANTINE_RANDOM_LENGTH << quarantine_shift can exceed 65535, but was passed to get_random_u16_uniform() whose bound is u16. With CONFIG_EXTENDED_SIZE_CLASSES, the smallest size class has quarantine_shift=13, so any SLAB_QUARANTINE_RANDOM_LENGTH >= 8 truncates the bound modulo 65536. Pick the random helper at compile time based on the worst-case bound: u16 when SLAB_QUARANTINE_RANDOM_LENGTH << (MAX_SLAB_SIZE_CLASS_SHIFT - MIN_SLAB_SIZE_CLASS_SHIFT) fits in u16 (the default), u32 otherwise. The worst case (65536 << 13 = 2^29) fits in u32, so u64 is never required. Add get_random_u32 and get_random_u32_uniform helpers.
c9656a6 to
b017d7d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
deallocate_small()computes:get_random_u16_uniform()takes au16bound, soslab_quarantine_random_lengthis silently truncated. WithCONFIG_EXTENDED_SIZE_CLASSES=true(the default),quarantine_shiftfor the smallest size class isMAX_SLAB_SIZE_CLASS_SHIFT - MIN_SLAB_SIZE_CLASS_SHIFT = 13, so the shifted length isSLAB_QUARANTINE_RANDOM_LENGTH * 8192. AnySLAB_QUARANTINE_RANDOM_LENGTH >= 8causes the shifted length to exceed the u16 range and truncate modulo 65536. Values that are multiples of 8 truncate to 0, causingget_random_u16_uniformto return 0 unconditionally and collapse the random quarantine to slot 0 for that size class. Non-multiples of 8 above the threshold truncate to a smaller nonzero bound, silently using only a prefix of the quarantine array. Without extended size classes, the threshold isSLAB_QUARANTINE_RANDOM_LENGTH >= 8atquarantine_shift = 10, with collapse-to-zero for multiples of 64.The static_assert at the top of h_malloc.c documents
SLAB_QUARANTINE_RANDOM_LENGTHas valid up to 65536, but most of that range silently misbehaves at the call site.The default configuration (
SLAB_QUARANTINE_RANDOM_LENGTH=1) shifts to 8192, which fits in u16 and is unaffected. The corresponding queue path usessize_tarithmetic directly without a uniform-bound call, so it is not affected.Fix: pick the random helper at compile time based on the worst-case bound. Use get_random_u16_uniform() when SLAB_QUARANTINE_RANDOM_LENGTH << (MAX_SLAB_SIZE_CLASS_SHIFT - MIN_SLAB_SIZE_CLASS_SHIFT) <= UINT16_MAX (which covers the default), get_random_u32_uniform() otherwise. The worst case is 65536 << 13 = 2^29, which fits in u32, so u64 is never required. Adds get_random_u32 and get_random_u32_uniform since they did not exist