Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] rust: id_pool: reserve_ids() and find_unused_id() panic when offset >= 
capacity
--

commit aa26fdd2bd4ce814afc1e6755fd4a71b9333439f
Author: Eliot Courtney <[email protected]>

rust: id_pool: add contiguous ID reservation

Add `IdPool::reserve_ids` which allocates a contiguous range with the
given offset, count, and alignment.

> diff --git a/rust/kernel/id_pool.rs b/rust/kernel/id_pool.rs
> index 384753fe0e44a..06a4c71c4c6c9 100644
> --- a/rust/kernel/id_pool.rs
> +++ b/rust/kernel/id_pool.rs

[ ... ]

> @@ -240,6 +246,32 @@ pub fn find_unused_id(&mut self, offset: usize) -> 
> Option<UnusedId<'_>> {
>      pub fn release_id(&mut self, id: usize) {
>          self.map.clear_bit(id);
>      }
> +
> +    /// Reserves a contiguous area of `count` IDs at or after `offset`.
> +    ///
> +    /// The start of the returned area is a multiple of `align`.
> +    ///
> +    /// Returns the reserved range upon success, or [`None`] if no such area 
> could be found.
> +    #[inline]
> +    #[must_use]
> +    pub fn reserve_ids(
> +        &mut self,
> +        offset: usize,
> +        count: NonZero<usize>,
> +        align: Alignment,
> +    ) -> Option<Range<usize>> {
> +        let start = self.map.next_zero_area(offset, count, align)?;

[Severity: High]
Does this code panic when offset is greater than or equal to pool.capacity()?

If a caller attempts to reserve an ID in an IdPool where the requested
offset is greater than or equal to pool.capacity(), IdPool::reserve_ids()
passes offset directly to BitmapVec::next_zero_area() without bounds validation.

This can trivially occur if a caller instantiates an empty pool
(IdPool::with_capacity(0)) or resumes searching for an ID by passing
offset = last_id + 1 when last_id was the last available ID.

The underlying BitmapVec::next_zero_area() function calls
next_zero_area_off() in rust/kernel/bitmap.rs, which contains a
bitmap_assert!(start < self.len()) that expands to a hard assert! under
CONFIG_RUST_BITMAP_HARDENED, leading to a kernel panic (denial of service).

Since IdPool is documented to return None to prompt a grow_request
when no IDs are available, failing to handle offset >= self.capacity()
gracefully breaks the resizing API and causes panics on legitimate resource
pool usage patterns.

It appears IdPool::find_unused_id() also shares this behavior when calling
self.map.next_zero_bit(offset)? without bounds checking.

> +        self.map.set(start, count);
> +        Some(start..start + count.get())
> +    }
> +
> +    /// Releases a contiguous area of IDs.
> +    #[inline]
> +    pub fn release_ids(&mut self, range: &Range<usize>) {
> +        if let Some(nbits) = NonZero::new(range.len()) {
> +            self.map.clear(range.start, nbits);
> +        }
> +    }
>  }

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=7

Reply via email to