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:
@@ -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`.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user