ANDROID: ashmem_rust: Add is_ashmem_file()

The minidump module iterates over open files and VMAs for each process
and reports information that is useful for debugging. A useful piece of
information is what ashmem files are currently referenced either via
a userspace memory mapping or a file descriptor. Therefore, add
is_ashmem_file() to aid in identifying those references.

Unfortunately, the logic that exports Rust symbols to other kernel
modules only considers the crates under the rust/ directory at the root
of the kernel repository. Since there's no support to include symbols
from crates defined outside of that repository, add
ashmem_rust_exports.c to export is_ashmem_file().

Changes from older versions of this patch:

- Reworded commit message for clarity.
- Implemented is_ashmem_file() in Rust, since android16-6.12+ will use
  Rust for ashmem.

Bug: 193397560
Change-Id: I5b7816ad4775e5cf2c4f41c28b1c8dacc2c85b7e
Signed-off-by: Isaac J. Manjarres <isaacmanjarres@google.com>
This commit is contained in:
Isaac J. Manjarres
2025-06-27 15:07:30 +00:00
committed by Isaac Manjarres
parent 0d890f867e
commit 6bdbae6ea9
4 changed files with 53 additions and 7 deletions

View File

@@ -3,3 +3,4 @@ ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_ASHMEM_C) += ashmem.o
obj-$(CONFIG_ASHMEM_RUST) += ashmem_rust.o
ashmem_rust-objs += ashmem_rust.o ashmem_rust_exports.o

View File

@@ -31,4 +31,6 @@ enum {
};
#endif
bool is_ashmem_file(struct file *file);
#endif /* _LINUX_ASHMEM_H */

View File

@@ -12,7 +12,8 @@
use core::{
pin::Pin,
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
ptr::null_mut,
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
};
use kernel::{
bindings::{self, ASHMEM_GET_PIN_STATUS, ASHMEM_PIN, ASHMEM_UNPIN},
@@ -71,6 +72,7 @@ fn has_cap_sys_admin() -> bool {
static NUM_PIN_IOCTLS_WAITING: AtomicUsize = AtomicUsize::new(0);
static IGNORE_UNSET_PROT_READ: AtomicBool = AtomicBool::new(false);
static IGNORE_UNSET_PROT_EXEC: AtomicBool = AtomicBool::new(false);
static ASHMEM_FOPS_PTR: AtomicPtr<bindings::file_operations> = AtomicPtr::new(null_mut());
fn shrinker_should_stop() -> bool {
NUM_PIN_IOCTLS_WAITING.load(Ordering::Relaxed) > 0
@@ -104,13 +106,20 @@ impl kernel::Module for AshmemModule {
ashmem_range::set_shrinker_enabled(true)?;
let ashmem_miscdevice_registration = KBox::pin_init(
MiscDeviceRegistration::register(MiscDeviceOptions {
name: c_str!("ashmem"),
}),
GFP_KERNEL,
)?;
let ashmem_miscdevice_ptr = ashmem_miscdevice_registration.as_raw();
// SAFETY: ashmem_miscdevice_registration is pinned and is never destroyed, so reading
// and storing the fops pointer this way should be fine.
let fops_ptr = unsafe { (*ashmem_miscdevice_ptr).fops };
ASHMEM_FOPS_PTR.store(fops_ptr.cast_mut(), Ordering::Relaxed);
Ok(Self {
_misc: KBox::pin_init(
MiscDeviceRegistration::register(MiscDeviceOptions {
name: c_str!("ashmem"),
}),
GFP_KERNEL,
)?,
_misc: ashmem_miscdevice_registration,
_toggle_unpin: AshmemToggleMisc::<AshmemToggleShrinker>::new()?,
_toggle_read: AshmemToggleMisc::<AshmemToggleRead>::new()?,
_toggle_exec: AshmemToggleMisc::<AshmemToggleExec>::new()?,
@@ -638,3 +647,18 @@ fn ashmem_memfd_ioctl_inner(file: &File, cmd: u32, arg: usize) -> Result<isize>
_ => Err(EINVAL),
}
}
/// # Safety
///
/// The caller must ensure that `file` is valid for the duration of this function.
#[no_mangle]
unsafe extern "C" fn is_ashmem_file(file: *mut bindings::file) -> bool {
let ashmem_fops_ptr = ASHMEM_FOPS_PTR.load(Ordering::Relaxed);
if file.is_null() || ashmem_fops_ptr.is_null() {
return false;
}
// SAFETY: Accessing the f_op field of a non-NULL file structure is always okay.
let fops_ptr = unsafe { (*file).f_op };
fops_ptr == ashmem_fops_ptr
}

View File

@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Symbols exported from the Ashmem Rust driver for loadable kernel modules to use.
*
* Copyright (c) 2025, Google LLC.
*/
#include <linux/export.h>
#include "ashmem.h"
/*
* List symbols that need to be exported to loadable kernel modules below. This is needed because
* the logic that exports symbols from Rust crates only considers the crates under the rust/
* directory at the root of the kernel repo. It currently does not support exporting symbols from
* other crates.
*/
EXPORT_SYMBOL_GPL(is_ashmem_file);