pub enum Protection {
None,
Read,
ReadWrite,
ReadExecute,
ReadWriteExecute,
}Expand description
The access a page range permits: which of read, write, and execute the CPU will allow.
A Region is created read/write so code or data can be written into it,
then moved to another protection with Region::protect. The
pattern a JIT follows is write xor execute (W^X): fill the region while it is
ReadWrite, then flip it to ReadExecute before
running the code. Memory that is writable and executable at the same time is a standing
invitation to turn a stray write into code execution, so ReadWriteExecute
exists for the rare cases that need it but should be avoided where the two-step flip works.
The five cases map directly onto the platform primitives: PROT_* bits for mprotect
on Unix, PAGE_* constants for VirtualProtect on Windows.
§Examples
use pager_lang::Protection;
assert!(Protection::ReadWrite.is_writable());
assert!(!Protection::ReadWrite.is_executable());
assert!(Protection::ReadExecute.is_executable());
assert!(!Protection::ReadExecute.is_writable());
// A guard page allows nothing at all.
assert!(!Protection::None.is_readable());Variants§
None
No access. Any read, write, or execute through the range faults. This is what guard pages carry.
Read
Read-only. Suitable for constant data that must not change once written.
ReadWrite
Read and write — the protection a freshly created Region starts
with, so machine code or data can be written into it.
ReadExecute
Read and execute. The target for finished JIT code: readable and runnable, but no longer writable, completing the W^X flip.
ReadWriteExecute
Read, write, and execute simultaneously. Convenient but it defeats W^X; prefer
writing under ReadWrite and flipping to
ReadExecute. Some hardened platforms refuse this protection
outright.
Implementations§
Source§impl Protection
impl Protection
Sourcepub const fn is_readable(self) -> bool
pub const fn is_readable(self) -> bool
Sourcepub const fn is_writable(self) -> bool
pub const fn is_writable(self) -> bool
Whether writes are permitted. True for ReadWrite and
ReadWriteExecute.
Region::write and
Region::as_mut_slice succeed exactly when the
region’s protection reports this true.
§Examples
use pager_lang::Protection;
assert!(Protection::ReadWrite.is_writable());
assert!(!Protection::ReadExecute.is_writable());Sourcepub const fn is_executable(self) -> bool
pub const fn is_executable(self) -> bool
Whether execution is permitted. True for ReadExecute and
ReadWriteExecute.
§Examples
use pager_lang::Protection;
assert!(Protection::ReadExecute.is_executable());
assert!(!Protection::ReadWrite.is_executable());Trait Implementations§
Source§impl Clone for Protection
impl Clone for Protection
Source§fn clone(&self) -> Protection
fn clone(&self) -> Protection
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for Protection
Source§impl Debug for Protection
impl Debug for Protection
Source§impl<'de> Deserialize<'de> for Protection
impl<'de> Deserialize<'de> for Protection
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Protection
Source§impl Hash for Protection
impl Hash for Protection
Source§impl PartialEq for Protection
impl PartialEq for Protection
Source§fn eq(&self, other: &Protection) -> bool
fn eq(&self, other: &Protection) -> bool
self and other values to be equal, and is used by ==.