From 4b433fd3104973dd0f3e85f739fefc5fd901da08 Mon Sep 17 00:00:00 2001 From: Josh Simmons Date: Fri, 18 Apr 2025 11:31:34 +0200 Subject: [PATCH] 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 Reviewed-by: Konstantin Seurer Fixes: 0cc9443e9b5 ("util: Add BITSET_EXTRACT") Part-of: (cherry picked from commit 922c3c53ceb77c0c51a6ed2937860dc812059c01) --- .pick_status.json | 2 +- src/util/bitset.h | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 917ca808ae6..d9f73f7b944 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/util/bitset.h b/src/util/bitset.h index cf9e59a01cf..8603fe5af0a 100644 --- a/src/util/bitset.h +++ b/src/util/bitset.h @@ -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) \