issue #772: added an memmap replacement to support selinux
This commit is contained in:
@@ -17,10 +17,15 @@ region = "2.0.0"
|
|||||||
libc = { version = "0.2.42" }
|
libc = { version = "0.2.42" }
|
||||||
errno = "0.2.4"
|
errno = "0.2.4"
|
||||||
target-lexicon = { version = "0.4.0" }
|
target-lexicon = { version = "0.4.0" }
|
||||||
|
memmap = { version = "0.7.0", optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["winbase", "memoryapi"] }
|
winapi = { version = "0.3", features = ["winbase", "memoryapi"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
selinux-fix = ['memmap']
|
||||||
|
default = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cranelift = { path = "../cranelift-umbrella", version = "0.34.0" }
|
cranelift = { path = "../cranelift-umbrella", version = "0.34.0" }
|
||||||
cranelift-frontend = { path = "../cranelift-frontend", version = "0.34.0" }
|
cranelift-frontend = { path = "../cranelift-frontend", version = "0.34.0" }
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
|
#[cfg(not(feature = "selinux-fix"))]
|
||||||
use errno;
|
use errno;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "selinux-fix"))]
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
|
#[cfg(feature = "selinux-fix")]
|
||||||
|
use memmap::MmapMut;
|
||||||
|
|
||||||
use region;
|
use region;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -11,6 +18,9 @@ fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
|
|||||||
|
|
||||||
/// A simple struct consisting of a pointer and length.
|
/// A simple struct consisting of a pointer and length.
|
||||||
struct PtrLen {
|
struct PtrLen {
|
||||||
|
#[cfg(feature = "selinux-fix")]
|
||||||
|
map: Option<MmapMut>,
|
||||||
|
|
||||||
ptr: *mut u8,
|
ptr: *mut u8,
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
@@ -19,6 +29,9 @@ impl PtrLen {
|
|||||||
/// Create a new empty `PtrLen`.
|
/// Create a new empty `PtrLen`.
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
#[cfg(feature = "selinux-fix")]
|
||||||
|
map: None,
|
||||||
|
|
||||||
ptr: ptr::null_mut(),
|
ptr: ptr::null_mut(),
|
||||||
len: 0,
|
len: 0,
|
||||||
}
|
}
|
||||||
@@ -26,13 +39,34 @@ impl PtrLen {
|
|||||||
|
|
||||||
/// Create a new `PtrLen` pointing to at least `size` bytes of memory,
|
/// Create a new `PtrLen` pointing to at least `size` bytes of memory,
|
||||||
/// suitably sized and aligned for memory protection.
|
/// suitably sized and aligned for memory protection.
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(all(not(target_os = "windows"), feature = "selinux-fix"))]
|
||||||
|
fn with_size(size: usize) -> Result<Self, String> {
|
||||||
|
let page_size = region::page::size();
|
||||||
|
let alloc_size = round_up_to_page_size(size, page_size);
|
||||||
|
let map = MmapMut::map_anon(alloc_size);
|
||||||
|
|
||||||
|
match map {
|
||||||
|
Ok(mut map) => {
|
||||||
|
// The order here is important; we assign the pointer first to get
|
||||||
|
// around compile time borrow errors.
|
||||||
|
Ok(Self {
|
||||||
|
ptr: map.as_mut_ptr(),
|
||||||
|
map: Some(map),
|
||||||
|
len: alloc_size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(e.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(not(target_os = "windows"), not(feature = "selinux-fix")))]
|
||||||
fn with_size(size: usize) -> Result<Self, String> {
|
fn with_size(size: usize) -> Result<Self, String> {
|
||||||
let mut ptr = ptr::null_mut();
|
let mut ptr = ptr::null_mut();
|
||||||
let page_size = region::page::size();
|
let page_size = region::page::size();
|
||||||
let alloc_size = round_up_to_page_size(size, page_size);
|
let alloc_size = round_up_to_page_size(size, page_size);
|
||||||
unsafe {
|
unsafe {
|
||||||
let err = libc::posix_memalign(&mut ptr, page_size, alloc_size);
|
let err = libc::posix_memalign(&mut ptr, page_size, alloc_size);
|
||||||
|
|
||||||
if err == 0 {
|
if err == 0 {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ptr: ptr as *mut u8,
|
ptr: ptr as *mut u8,
|
||||||
@@ -122,11 +156,26 @@ impl Memory {
|
|||||||
pub fn set_readable_and_executable(&mut self) {
|
pub fn set_readable_and_executable(&mut self) {
|
||||||
self.finish_current();
|
self.finish_current();
|
||||||
|
|
||||||
for &PtrLen { ptr, len } in &self.allocations[self.executable..] {
|
#[cfg(feature = "selinux-fix")]
|
||||||
if len != 0 {
|
{
|
||||||
unsafe {
|
for &PtrLen { ref map, ptr, len } in &self.allocations[self.executable..] {
|
||||||
region::protect(ptr, len, region::Protection::ReadExecute)
|
if len != 0 && map.is_some() {
|
||||||
.expect("unable to make memory readable+executable");
|
unsafe {
|
||||||
|
region::protect(ptr, len, region::Protection::ReadExecute)
|
||||||
|
.expect("unable to make memory readable+executable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "selinux-fix"))]
|
||||||
|
{
|
||||||
|
for &PtrLen { ptr, len } in &self.allocations[self.executable..] {
|
||||||
|
if len != 0 {
|
||||||
|
unsafe {
|
||||||
|
region::protect(ptr, len, region::Protection::ReadExecute)
|
||||||
|
.expect("unable to make memory readable+executable");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,11 +185,26 @@ impl Memory {
|
|||||||
pub fn set_readonly(&mut self) {
|
pub fn set_readonly(&mut self) {
|
||||||
self.finish_current();
|
self.finish_current();
|
||||||
|
|
||||||
for &PtrLen { ptr, len } in &self.allocations[self.executable..] {
|
#[cfg(feature = "selinux-fix")]
|
||||||
if len != 0 {
|
{
|
||||||
unsafe {
|
for &PtrLen { ref map, ptr, len } in &self.allocations[self.executable..] {
|
||||||
region::protect(ptr, len, region::Protection::Read)
|
if len != 0 && map.is_some() {
|
||||||
.expect("unable to make memory readonly");
|
unsafe {
|
||||||
|
region::protect(ptr, len, region::Protection::Read)
|
||||||
|
.expect("unable to make memory readonly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "selinux-fix"))]
|
||||||
|
{
|
||||||
|
for &PtrLen { ptr, len } in &self.allocations[self.executable..] {
|
||||||
|
if len != 0 {
|
||||||
|
unsafe {
|
||||||
|
region::protect(ptr, len, region::Protection::Read)
|
||||||
|
.expect("unable to make memory readonly");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user