The size of a.data_type is set abnormally large, causing shift-out-of-bounds. To fix this, we need to add validation on a.data_type in alloc_lru_idx_fragmentation().
Reported-by: [email protected] Fixes: 260af1562ec1 ("bcachefs: Kill alloc_v4.fragmentation_lru") Signed-off-by: Jeongjun Park <[email protected]> --- fs/bcachefs/alloc_background.h | 3 +++ fs/bcachefs/disk_accounting_format.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h index f8e87c6721b1..66a334e2edcd 100644 --- a/fs/bcachefs/alloc_background.h +++ b/fs/bcachefs/alloc_background.h @@ -168,6 +168,9 @@ static inline bool data_type_movable(enum bch_data_type type) static inline u64 alloc_lru_idx_fragmentation(struct bch_alloc_v4 a, struct bch_dev *ca) { + if (a.data_type > BCH_DATA_TYPE_MAX) + return 0; + if (!data_type_movable(a.data_type) || !bch2_bucket_sectors_fragmented(ca, a)) return 0; diff --git a/fs/bcachefs/disk_accounting_format.h b/fs/bcachefs/disk_accounting_format.h index 7b6e6c97e6aa..0232bc9f590d 100644 --- a/fs/bcachefs/disk_accounting_format.h +++ b/fs/bcachefs/disk_accounting_format.h @@ -72,6 +72,8 @@ enum bch_data_type { BCH_DATA_NR }; +#define BCH_DATA_TYPE_MAX 10 + static inline bool data_type_is_empty(enum bch_data_type type) { switch (type) { --
