From f00fcf5bde3caf96364c5374bdf3beb8814a005a Mon Sep 17 00:00:00 2001 From: Xinyi Yu <1809327837@qq.com> Date: Mon, 9 Feb 2026 11:52:05 +0000 Subject: [PATCH] Prevents ID allocation beyond bitmap bounds --- kernel/src/fs/utils/id_bitmap.rs | 31 +++++++++++++++++++++++++++++++ ostd/libs/id-alloc/src/lib.rs | 24 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/kernel/src/fs/utils/id_bitmap.rs b/kernel/src/fs/utils/id_bitmap.rs index 1a7f8c434..768db0429 100644 --- a/kernel/src/fs/utils/id_bitmap.rs +++ b/kernel/src/fs/utils/id_bitmap.rs @@ -108,6 +108,11 @@ impl IdBitmap { return None; } + let end = self.first_available_id.checked_add(count)?; + if end > self.len { + return None; + } + // Scan the bitmap from the position `first_available_id` // for the first `count` number of consecutive 0's. let allocated_range = { @@ -191,3 +196,29 @@ impl Debug for IdBitmap { .finish() } } + +#[cfg(ktest)] +mod test { + use alloc::vec; + + use aster_block::BLOCK_SIZE; + use ostd::prelude::ktest; + + use super::IdBitmap; + + #[ktest] + fn bitmap_alloc_out_of_bounds() { + let buf = vec![0; BLOCK_SIZE].into_boxed_slice(); + + let capacity = BLOCK_SIZE as u16 * 8; + let mut bitmap = IdBitmap::from_buf(buf, capacity); + + for _ in 0..capacity { + assert!(bitmap.alloc().is_some()); + } + + // Allocating one more ID should fail since the + // bitmap's `first_available_id` + `count` is out of bounds. + assert!(bitmap.alloc_consecutive(1).is_none()); + } +} diff --git a/ostd/libs/id-alloc/src/lib.rs b/ostd/libs/id-alloc/src/lib.rs index 9e7141284..e98f60afb 100644 --- a/ostd/libs/id-alloc/src/lib.rs +++ b/ostd/libs/id-alloc/src/lib.rs @@ -54,6 +54,11 @@ impl IdAlloc { return None; } + let end = self.first_available_id.checked_add(count)?; + if end > self.bitset.len() { + return None; + } + // Scan the bitmap from the position `first_available_id` // for the first `count` number of consecutive 0's. let allocated_range = { @@ -163,3 +168,22 @@ impl Debug for IdAlloc { .finish() } } + +#[cfg(test)] +mod test { + use super::IdAlloc; + + #[test] + fn bitmap_alloc_out_of_bounds() { + let capacity = 16; + let mut bitmap = IdAlloc::with_capacity(capacity); + + for _ in 0..capacity { + assert!(bitmap.alloc().is_some()); + } + + // Allocating one more ID should fail since the + // bitmap's `first_available_id` + `count` is out of bounds. + assert!(bitmap.alloc_consecutive(1).is_none()); + } +}