ANDROID: rust_binder: don't drop AllocationInfo in reservation_commit

The destructor of AllocationInfo could potentially sleep. Don't call it
from reservation_commit.

Reported-by: Gary Guo <gary@garyguo.net>
Fixes: dac7c66bc9 ("ANDROID: rust_binder: move Rust Binder in preparation for GKI module")
Change-Id: Iea4d675c7b9db51019739c0b462b9108f7fecf0b
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2025-08-08 13:27:06 +00:00
committed by Treehugger Robot
parent 138082a939
commit 02e487e3c1
4 changed files with 12 additions and 21 deletions

View File

@@ -1058,10 +1058,10 @@ impl Process {
}
}
pub(crate) fn buffer_make_freeable(&self, offset: usize, data: Option<AllocationInfo>) {
pub(crate) fn buffer_make_freeable(&self, offset: usize, mut data: Option<AllocationInfo>) {
let mut inner = self.inner.lock();
if let Some(ref mut mapping) = &mut inner.mapping {
if mapping.alloc.reservation_commit(offset, data).is_err() {
if mapping.alloc.reservation_commit(offset, &mut data).is_err() {
pr_warn!("Offset {} failed to be marked freeable\n", offset);
}
}

View File

@@ -189,7 +189,7 @@ impl<T> ArrayRangeAllocator<T> {
Ok(freed_range)
}
pub(crate) fn reservation_commit(&mut self, offset: usize, data: Option<T>) -> Result {
pub(crate) fn reservation_commit(&mut self, offset: usize, data: &mut Option<T>) -> Result {
// This could use a binary search, but linear scans are usually faster for small arrays.
let range = self
.ranges
@@ -201,7 +201,7 @@ impl<T> ArrayRangeAllocator<T> {
return Err(ENOENT);
};
range.state = DescriptorState::Allocated(reservation.clone().allocate(data));
range.state = DescriptorState::Allocated(reservation.clone().allocate(data.take()));
Ok(())
}

View File

@@ -239,7 +239,10 @@ impl<T> RangeAllocator<T> {
}
/// Called when an allocation is no longer in use by the kernel.
pub(crate) fn reservation_commit(&mut self, offset: usize, data: Option<T>) -> Result {
///
/// The value in `data` will be stored, if any. A mutable reference is used to avoid dropping
/// the `T` when an error is returned.
pub(crate) fn reservation_commit(&mut self, offset: usize, data: &mut Option<T>) -> Result {
match &mut self.inner {
Impl::Empty(_size) => Err(EINVAL),
Impl::Array(array) => array.reservation_commit(offset, data),

View File

@@ -306,30 +306,18 @@ impl<T> TreeRangeAllocator<T> {
Ok(freed_range)
}
pub(crate) fn reservation_commit(&mut self, offset: usize, data: Option<T>) -> Result {
let desc = self.tree.get_mut(&offset).ok_or_else(|| {
pr_warn!(
"ENOENT from range_alloc.reservation_commit - offset: {}",
offset
);
ENOENT
})?;
pub(crate) fn reservation_commit(&mut self, offset: usize, data: &mut Option<T>) -> Result {
let desc = self.tree.get_mut(&offset).ok_or(ENOENT)?;
desc.try_change_state(|state| match state {
Some((DescriptorState::Reserved(reservation), free_node_res)) => (
Some((
DescriptorState::Allocated(reservation.allocate(data)),
DescriptorState::Allocated(reservation.allocate(data.take())),
free_node_res,
)),
Ok(()),
),
other => {
pr_warn!(
"ENOENT from range_alloc.reservation_commit - offset: {}",
offset
);
(other, Err(ENOENT))
}
other => (other, Err(ENOENT)),
})
}