Skip to content

Commit 803c8a9

Browse files
V4belgregkh
authored andcommitted
rust_binder: use a u64 stride when cleaning up the offsets array
Allocation's Drop walks the offsets array (binder_size_t = u64 entries), cleaning up the objects, but it used usize instead of u64 for both the stride and the per-entry read. On 64-bit kernels (usize == u64) this is harmless, but on 32-bit kernels it walks the 8-byte entries in 4-byte steps, iterating an N-entry array 2N times, and reads the always-zero high word as offset 0, cleaning up the object at offset 0 N extra times. As a result the referenced node or handle ends up with a lower reference count than it actually has (a refcount over-decrement), and binder's reference accounting is corrupted; for example, the owner can be notified of a strong reference release (BR_RELEASE) even though references still remain. Change the stride to u64, and read each entry as a u64, narrowing it to usize with try_into(). On 32-bit ARM, when this over-decrement would drive a count below zero, the driver's existing refcount guard refuses it and fires: rust_binder: Failure: refcount underflow! Cc: stable <stable@kernel.org> Fixes: eafedbc ("rust_binder: add Rust Binder driver") Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com> Acked-by: Carlos Llamas <cmllamas@google.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://patch.msgid.link/ahw3tFhLz9bMMJAO@v4bel Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f223d27 commit 803c8a9

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

drivers/android/binder/allocation.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl Drop for Allocation {
259259

260260
if let Some(offsets) = info.offsets.clone() {
261261
let view = AllocationView::new(self, offsets.start);
262-
for i in offsets.step_by(size_of::<usize>()) {
262+
for i in offsets.step_by(size_of::<u64>()) {
263263
if view.cleanup_object(i).is_err() {
264264
pr_warn!("Error cleaning up object at offset {}\n", i)
265265
}
@@ -420,7 +420,8 @@ impl<'a> AllocationView<'a> {
420420
}
421421

422422
fn cleanup_object(&self, index_offset: usize) -> Result {
423-
let offset = self.alloc.read(index_offset)?;
423+
let offset = self.alloc.read::<u64>(index_offset)?;
424+
let offset: usize = offset.try_into().map_err(|_| EINVAL)?;
424425
let header = self.read::<BinderObjectHeader>(offset)?;
425426
match header.type_ {
426427
BINDER_TYPE_WEAK_BINDER | BINDER_TYPE_BINDER => {

0 commit comments

Comments
 (0)