ANDROID: rust_binder: enforce that overflow in ptr_align is checked

Currently passing a very large integer to ptr_align can panic due to an
integer overflow. To fix this, change ptr_align to return an Option so
that the caller cannot forget to handle overflow when calling ptr_align.

Bug: 426634893
Change-Id: Iaf901fb2032d31b3054e023deaf227ecae0c81f2
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2025-06-23 14:15:27 +00:00
parent dc4eb8482b
commit b6652492f9
3 changed files with 11 additions and 11 deletions

View File

@@ -283,9 +283,9 @@ impl DeliverToRead for DeliverCode {
}
}
const fn ptr_align(value: usize) -> usize {
fn ptr_align(value: usize) -> Option<usize> {
let size = core::mem::size_of::<usize>() - 1;
(value + size) & !size
Some(value.checked_add(size)? & !size)
}
// SAFETY: We call register in `init`.

View File

@@ -205,7 +205,7 @@ impl UnusedBufferSpace {
/// into the buffer is returned.
fn claim_next(&mut self, size: usize) -> Result<usize> {
// We require every chunk to be aligned.
let size = ptr_align(size);
let size = ptr_align(size).ok_or(EINVAL)?;
let new_offset = self.offset.checked_add(size).ok_or(EINVAL)?;
if new_offset <= self.limit {
@@ -1066,15 +1066,15 @@ impl Thread {
};
let data_size = trd.data_size.try_into().map_err(|_| EINVAL)?;
let aligned_data_size = ptr_align(data_size);
let aligned_data_size = ptr_align(data_size).ok_or(EINVAL)?;
let offsets_size = trd.offsets_size.try_into().map_err(|_| EINVAL)?;
let aligned_offsets_size = ptr_align(offsets_size);
let aligned_offsets_size = ptr_align(offsets_size).ok_or(EINVAL)?;
let buffers_size = tr.buffers_size.try_into().map_err(|_| EINVAL)?;
let aligned_buffers_size = ptr_align(buffers_size);
let aligned_secctx_size = secctx
.as_ref()
.map(|(_, ctx)| ptr_align(ctx.len()))
.unwrap_or(0);
let aligned_buffers_size = ptr_align(buffers_size).ok_or(EINVAL)?;
let aligned_secctx_size = match secctx.as_ref() {
Some((_offset, ctx)) => ptr_align(ctx.len()).ok_or(EINVAL)?,
None => 0,
};
// This guarantees that at least `sizeof(usize)` bytes will be allocated.
let len = usize::max(

View File

@@ -423,7 +423,7 @@ impl DeliverToRead for Transaction {
tr.data.ptr.buffer = self.data_address as _;
tr.offsets_size = self.offsets_size as _;
if tr.offsets_size > 0 {
tr.data.ptr.offsets = (self.data_address + ptr_align(self.data_size)) as _;
tr.data.ptr.offsets = (self.data_address + ptr_align(self.data_size).unwrap()) as _;
}
tr.sender_euid = self.sender_euid.into_uid_in_current_ns();
tr.sender_pid = 0;