ANDROID: ashmem: use strncpy_from_user in set_name

Ashmem expected that it could always read ASHMEM_NAME_LEN bytes from the
provided pointer even if the actual string was shorter. This assumption
turns out to be false.

Bug: 409422661
Change-Id: I617be6c91947d44ec80b894c41fabe0f5c539eae
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
Alice Ryhl
2025-04-18 21:50:30 +00:00
committed by Treehugger Robot
parent 56dea476ea
commit ba971cd36a
2 changed files with 21 additions and 9 deletions
+8 -9
View File
@@ -284,17 +284,16 @@ impl MiscDevice for Ashmem {
}
impl Ashmem {
fn set_name(&self, mut reader: UserSliceReader) -> Result<isize> {
fn set_name(&self, reader: UserSliceReader) -> Result<isize> {
let mut local_name = [0u8; ASHMEM_NAME_LEN];
reader.read_slice(&mut local_name)?;
let mut len = reader.strncpy_from_user(&mut local_name)?;
// Find the zero terminator. If the zero terminator is missing, the string is truncated to
// `ASHMEM_NAME_LEN-1` so that `get_name` can return it and has enough space to add a zero
// terminator.
let len = local_name
.iter()
.position(|&c| c == 0)
.unwrap_or(local_name.len() - 1);
// If the zero terminator is missing, the string is truncated to `ASHMEM_NAME_LEN-1` so
// that `get_name` can return it and has enough space to add a zero terminator.
if len == ASHMEM_NAME_LEN {
len -= 1;
local_name[len] = 0;
}
let mut v = KVec::with_capacity(len, GFP_KERNEL)?;
v.extend_from_slice(&local_name[..len], GFP_KERNEL)?;
+13
View File
@@ -294,6 +294,19 @@ impl UserSliceReader {
unsafe { buf.set_len(buf.len() + len) };
Ok(())
}
/// Reads a nul-terminated string into the provided buffer and returns the length.
pub fn strncpy_from_user(self, buf: &mut [u8]) -> Result<usize> {
let max = usize::min(self.length, buf.len()) as isize;
// SAFETY: `buf` is valid for writing `buf.len()` bytes.
let res =
unsafe { bindings::strncpy_from_user(buf.as_mut_ptr(), self.ptr as *const u8, max) };
if res >= 0 {
Ok(res as usize)
} else {
Err(Error::from_errno(res as i32))
}
}
}
/// A writer for [`UserSlice`].