Function nc::mprotect

source ·
pub unsafe fn mprotect(addr: usize, len: size_t, prot: i32) -> Result<(), Errno>
Expand description

Set protection on a region of memory.

§Example

// Initialize an anonymous mapping with 4 pages.
let map_length = 4 * nc::PAGE_SIZE;
let addr = unsafe {
    nc::mmap(
        0,
        map_length,
        nc::PROT_READ | nc::PROT_WRITE,
        nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
        -1,
        0,
    )
};
assert!(addr.is_ok());
let addr = addr.unwrap();

// Set the third page readonly. And we will run into SIGSEGV when updating it.
let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
assert!(ret.is_ok());

let ret = unsafe { nc::munmap(addr, map_length) };
assert!(ret.is_ok());
Examples found in repository?
examples/mprotect.rs (line 59)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn main() {
    // Register SIGSEGV handler.
    let sa = nc::sigaction_t {
        sa_handler: handle_segfault as nc::sighandler_t,
        sa_flags: nc::SA_SIGINFO,
        ..nc::sigaction_t::default()
    };
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe {
        nc::rt_sigaction(
            nc::SIGSEGV,
            &sa,
            &mut old_sa,
            mem::size_of::<nc::sigset_t>(),
        )
    };
    assert!(ret.is_ok());

    // Initialize an anonymous mapping with 4 pages.
    let map_length = 4 * nc::PAGE_SIZE;
    #[cfg(target_arch = "arm")]
    let addr = unsafe {
        nc::mmap2(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };

    #[cfg(not(target_arch = "arm"))]
    let addr = unsafe {
        nc::mmap(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };
    assert!(addr.is_ok());
    let addr = addr.unwrap();

    // Set the third page readonly. And we will run into SIGSEGV when updating it.
    let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
    assert!(ret.is_ok());

    for p in addr..(addr + map_length) {
        unsafe {
            *(p as *mut u8) = 42;
        }
    }

    let ret = unsafe { nc::munmap(addr, map_length) };
    assert!(ret.is_ok());
    unsafe { nc::exit(0) };
}