ANDROID: ashmem_rust: add toggle for PROT_READ
The memfd type simulates SET_PROT_MASK using file seals, but there's no file seal to prevent mapping readable memory. Thus, add a toggle that removes the ability to unset the PROT_READ bit on an ashmem file. Bug: 370906207 Change-Id: I2d0347ce124d7d6d543cff765f77b28202cf327f Signed-off-by: Alice Ryhl <aliceryhl@google.com>
This commit is contained in:
committed by
Suren Baghdasaryan
parent
5e60c48050
commit
e8bed58ffd
@@ -13,7 +13,7 @@
|
||||
use core::{
|
||||
ffi::c_int,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
};
|
||||
use kernel::{
|
||||
bindings::{self, ASHMEM_GET_PIN_STATUS, ASHMEM_PIN, ASHMEM_UNPIN},
|
||||
@@ -50,7 +50,7 @@ mod shmem;
|
||||
use shmem::ShmemFile;
|
||||
|
||||
mod ashmem_toggle;
|
||||
use ashmem_toggle::{AshmemToggleMisc, AshmemToggleShrinker};
|
||||
use ashmem_toggle::{AshmemToggleMisc, AshmemToggleRead, AshmemToggleShrinker};
|
||||
|
||||
/// Does PROT_READ imply PROT_EXEC for this task?
|
||||
fn read_implies_exec(task: &Task) -> bool {
|
||||
@@ -66,6 +66,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);
|
||||
|
||||
fn shrinker_should_stop() -> bool {
|
||||
NUM_PIN_IOCTLS_WAITING.load(Ordering::Relaxed) > 0
|
||||
@@ -82,6 +83,7 @@ module! {
|
||||
struct AshmemModule {
|
||||
_misc: Pin<Box<MiscDeviceRegistration<Ashmem>>>,
|
||||
_toggle_unpin: Pin<Box<MiscDeviceRegistration<AshmemToggleMisc<AshmemToggleShrinker>>>>,
|
||||
_toggle_read: Pin<Box<MiscDeviceRegistration<AshmemToggleMisc<AshmemToggleRead>>>>,
|
||||
}
|
||||
|
||||
impl kernel::Module for AshmemModule {
|
||||
@@ -105,6 +107,7 @@ impl kernel::Module for AshmemModule {
|
||||
GFP_KERNEL,
|
||||
)?,
|
||||
_toggle_unpin: AshmemToggleMisc::<AshmemToggleShrinker>::new()?,
|
||||
_toggle_read: AshmemToggleMisc::<AshmemToggleRead>::new()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -340,6 +343,11 @@ impl Ashmem {
|
||||
prot |= PROT_EXEC;
|
||||
}
|
||||
|
||||
if IGNORE_UNSET_PROT_READ.load(Ordering::Relaxed) {
|
||||
// Add back PROT_READ if asma.prot_mask has it.
|
||||
prot |= asma.prot_mask & PROT_READ;
|
||||
}
|
||||
|
||||
// The user can only remove, not add, protection bits.
|
||||
if (asma.prot_mask & prot) != prot {
|
||||
return Err(EINVAL);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
//! Provides knobs for Rust ashmem.
|
||||
|
||||
use crate::ashmem_range;
|
||||
use core::marker::PhantomData;
|
||||
use crate::{ashmem_range, IGNORE_UNSET_PROT_READ};
|
||||
use core::{marker::PhantomData, sync::atomic::Ordering};
|
||||
use kernel::{
|
||||
c_str,
|
||||
error::to_result,
|
||||
@@ -79,3 +79,16 @@ impl AshmemToggle for AshmemToggleShrinker {
|
||||
ashmem_range::get_shrinker_enabled()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AshmemToggleRead;
|
||||
|
||||
impl AshmemToggle for AshmemToggleRead {
|
||||
const NAME: &'static CStr = c_str!("ashmem_ignore_unset_prot_read");
|
||||
fn set(enabled: bool) -> Result<()> {
|
||||
IGNORE_UNSET_PROT_READ.store(enabled, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
fn get() -> bool {
|
||||
IGNORE_UNSET_PROT_READ.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user