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:
committed by
Treehugger Robot
parent
138082a939
commit
02e487e3c1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user