util: Fix BITSET_EXTRACT out-of-bounds read

In some situations the implementation of `BITSET_EXTRACT` would read
beyond the size of the bitset due to an unconditional + 1 in the address
calculation.

Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Fixes: 0cc9443e9b ("util: Add BITSET_EXTRACT")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34605>
(cherry picked from commit 922c3c53ce)
This commit is contained in:
Josh Simmons 2025-04-18 11:31:34 +02:00 committed by Eric Engestrom
parent 4f7345f226
commit 4b433fd310
2 changed files with 5 additions and 6 deletions

View file

@ -5324,7 +5324,7 @@
"description": "util: Fix `BITSET_EXTRACT` out-of-bounds read",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "0cc9443e9b5419f927a3f81d4ed9b7e9c1829907",
"notes": null

View file

@ -284,11 +284,10 @@ static inline unsigned
__bitset_extract(const BITSET_WORD *r, unsigned start, unsigned count)
{
unsigned shift = start % BITSET_WORDBITS;
unsigned lower = r[BITSET_BITWORD(start)] >> shift;
unsigned upper = shift ? r[BITSET_BITWORD(start) + 1] << (32 - shift) : 0;
unsigned total = lower | upper;
return count != 32 ? total & ((1u << count) - 1u) : total;
BITSET_WORD lower = r[BITSET_BITWORD(start)] >> shift;
BITSET_WORD upper = shift ? r[BITSET_BITWORD(start + count - 1)] << (BITSET_WORDBITS - shift) : 0;
BITSET_WORD total = lower | upper;
return count != BITSET_WORDBITS ? total & ((1u << count) - 1u) : total;
}
#define BITSET_EXTRACT(x, s, c) \