Skip to content

Commit a5688ad

Browse files
committed
auto merge of #15588 : alexcrichton/rust/issue-15478, r=cmr
If modified, you can safely unmap arbitrary memory. These fields are not intended to be modified, so read-only accessors are the only ones that are provided. Closes #15478
2 parents 8a2b7a5 + fb02d54 commit a5688ad

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

src/libgreen/stack.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::ptr;
1112
use std::sync::atomics;
1213
use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
13-
MapNonStandardFlags, MapVirtual, getenv};
14+
MapNonStandardFlags, getenv};
1415
use libc;
1516

1617
/// A task's stack. The name "Stack" is a vestige of segmented stacks.
1718
pub struct Stack {
18-
buf: MemoryMap,
19+
buf: Option<MemoryMap>,
1920
min_size: uint,
2021
valgrind_id: libc::c_uint,
2122
}
@@ -52,11 +53,11 @@ impl Stack {
5253
// guaranteed to be aligned properly.
5354
if !protect_last_page(&stack) {
5455
fail!("Could not memory-protect guard page. stack={}, errno={}",
55-
stack.data, errno());
56+
stack.data(), errno());
5657
}
5758

5859
let mut stk = Stack {
59-
buf: stack,
60+
buf: Some(stack),
6061
min_size: size,
6162
valgrind_id: 0
6263
};
@@ -71,22 +72,23 @@ impl Stack {
7172
/// Create a 0-length stack which starts (and ends) at 0.
7273
pub unsafe fn dummy_stack() -> Stack {
7374
Stack {
74-
buf: MemoryMap { data: 0 as *mut u8, len: 0, kind: MapVirtual },
75+
buf: None,
7576
min_size: 0,
7677
valgrind_id: 0
7778
}
7879
}
7980

8081
/// Point to the low end of the allocated stack
8182
pub fn start(&self) -> *const uint {
82-
self.buf.data as *const uint
83+
self.buf.as_ref().map(|m| m.data() as *const uint)
84+
.unwrap_or(ptr::null())
8385
}
8486

8587
/// Point one uint beyond the high end of the allocated stack
8688
pub fn end(&self) -> *const uint {
87-
unsafe {
88-
self.buf.data.offset(self.buf.len as int) as *const uint
89-
}
89+
self.buf.as_ref().map(|buf| unsafe {
90+
buf.data().offset(buf.len() as int) as *const uint
91+
}).unwrap_or(ptr::null())
9092
}
9193
}
9294

@@ -96,7 +98,7 @@ fn protect_last_page(stack: &MemoryMap) -> bool {
9698
// This may seem backwards: the start of the segment is the last page?
9799
// Yes! The stack grows from higher addresses (the end of the allocated
98100
// block) to lower addresses (the start of the allocated block).
99-
let last_page = stack.data as *mut libc::c_void;
101+
let last_page = stack.data() as *mut libc::c_void;
100102
libc::mprotect(last_page, page_size() as libc::size_t,
101103
libc::PROT_NONE) != -1
102104
}
@@ -106,7 +108,7 @@ fn protect_last_page(stack: &MemoryMap) -> bool {
106108
fn protect_last_page(stack: &MemoryMap) -> bool {
107109
unsafe {
108110
// see above
109-
let last_page = stack.data as *mut libc::c_void;
111+
let last_page = stack.data() as *mut libc::c_void;
110112
let mut old_prot: libc::DWORD = 0;
111113
libc::VirtualProtect(last_page, page_size() as libc::SIZE_T,
112114
libc::PAGE_NOACCESS,

src/libstd/os.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,12 +1277,9 @@ pub fn page_size() -> uint {
12771277
/// The memory map is released (unmapped) when the destructor is run, so don't
12781278
/// let it leave scope by accident if you want it to stick around.
12791279
pub struct MemoryMap {
1280-
/// Pointer to the memory created or modified by this map.
1281-
pub data: *mut u8,
1282-
/// Number of bytes this map applies to
1283-
pub len: uint,
1284-
/// Type of mapping
1285-
pub kind: MemoryMapKind,
1280+
data: *mut u8,
1281+
len: uint,
1282+
kind: MemoryMapKind,
12861283
}
12871284

12881285
/// Type of memory map
@@ -1617,6 +1614,15 @@ impl Drop for MemoryMap {
16171614
}
16181615
}
16191616

1617+
impl MemoryMap {
1618+
/// Returns the pointer to the memory created or modified by this map.
1619+
pub fn data(&self) -> *mut u8 { self.data }
1620+
/// Returns the number of bytes this map applies to.
1621+
pub fn len(&self) -> uint { self.len }
1622+
/// Returns the type of mapping this represents.
1623+
pub fn kind(&self) -> MemoryMapKind { self.kind }
1624+
}
1625+
16201626
#[cfg(target_os = "linux")]
16211627
pub mod consts {
16221628
pub use os::arch_consts::ARCH;

0 commit comments

Comments
 (0)