ANDROID: ashmem_rust: Add support for providing an ashmem region's name

Given a pointer to a file structure that represents an ashmem region,
and a character array, populate the array with the name of the ashmem
region. This should only be used for dumping information about ashmem
regions in debug scenarios.

Bug: 193397560
Change-Id: Iafd000983eb4e2963a46163fa4b62eda07445e1e
Signed-off-by: Isaac J. Manjarres <isaacmanjarres@google.com>
This commit is contained in:
Isaac J. Manjarres
2025-07-03 01:03:29 +00:00
committed by Isaac Manjarres
parent 6bdbae6ea9
commit eb50f663c4
3 changed files with 47 additions and 0 deletions

View File

@@ -32,5 +32,6 @@ enum {
#endif
bool is_ashmem_file(struct file *file);
int ashmem_area_name(struct file *file, char *name);
#endif /* _LINUX_ASHMEM_H */

View File

@@ -30,6 +30,7 @@ use kernel::{
seq_file::{seq_print, SeqFile},
sync::{new_mutex, Mutex, UniqueArc},
task::Task,
types::ForeignOwnable,
uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
};
@@ -662,3 +663,47 @@ unsafe extern "C" fn is_ashmem_file(file: *mut bindings::file) -> bool {
let fops_ptr = unsafe { (*file).f_op };
fops_ptr == ashmem_fops_ptr
}
/// # Safety
///
/// The caller must ensure that `file` references a valid file for the duration of 'a.
unsafe fn get_ashmem_area<'a>(file: *mut bindings::file) -> Result<&'a Ashmem, Error> {
// SAFETY: Caller ensures that file is valid, so this should be safe.
if unsafe { is_ashmem_file(file) } {
return Err(EINVAL);
}
// SAFETY: Given that this is an ashmem file, it should be safe to access the private_data
// field containing the Ashmem struct.
let private = unsafe { (*file).private_data };
// SAFETY: Since this is an ashmem file, we know the type of the struct and can reference it
// safely.
let ashmem = unsafe { <<Ashmem as MiscDevice>::Ptr as ForeignOwnable>::borrow(private) };
Ok(ashmem.get_ref())
}
/// # Safety
///
/// The caller must ensure the following prior to invoking this function:
/// 1. `name` is valid for writing and at least of size ASHMEM_FULL_NAME_LEN.
/// 2. `file` is valid for the duration of this function.
#[no_mangle]
unsafe extern "C" fn ashmem_area_name(
file: *mut bindings::file,
name: *mut kernel::ffi::c_char,
) -> c_int {
if name.is_null() {
return EINVAL.to_errno() as c_int;
}
// SAFETY: file is valid for the duration of this function.
match unsafe { get_ashmem_area(file) } {
Ok(ashmem) => {
let name_buffer = name.cast::<[u8; ASHMEM_FULL_NAME_LEN]>();
// SAFETY: Caller guarantees that the pointer is valid for writing.
ashmem.inner.lock().full_name(unsafe { &mut *name_buffer });
0
}
Err(err) => err.to_errno() as c_int,
}
}

View File

@@ -17,3 +17,4 @@
* other crates.
*/
EXPORT_SYMBOL_GPL(is_ashmem_file);
EXPORT_SYMBOL_GPL(ashmem_area_name);