Skip to content

Commit 4c3a5a5

Browse files
authored
Rollup merge of #69969 - iximeow:sigstack-guard-page, r=cuviper
unix: Set a guard page at the end of signal stacks This mitigates possible issues when signal stacks overflow, which could manifest as segfaults or in unlucky circumstances possible clobbering of other memory values as stack overflows tend to enable. I went ahead and made a PR for this because it's a pretty small change, though if I should open an issue/RFC for this and discuss there first I'll happily do so. I've also added some example programs that demonstrate the uncomfortably clobber-happy behavior we currently have, and the segfaults that could/should result instead, [here](https://github.com/iximeow/jubilant-train).
2 parents 73c3a49 + 28eeea6 commit 4c3a5a5

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

Diff for: src/libstd/sys/unix/stack_overflow.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ mod imp {
4545
use libc::{mmap, munmap};
4646
use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL};
4747
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
48-
use libc::{MAP_ANON, MAP_PRIVATE, PROT_READ, PROT_WRITE, SIGSEGV};
48+
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
4949

50+
use crate::sys::unix::os::page_size;
5051
use crate::sys_common::thread_info;
5152

5253
#[cfg(any(target_os = "linux", target_os = "android"))]
@@ -137,12 +138,22 @@ mod imp {
137138
}
138139

139140
unsafe fn get_stackp() -> *mut libc::c_void {
140-
let stackp =
141-
mmap(ptr::null_mut(), SIGSTKSZ, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
141+
let stackp = mmap(
142+
ptr::null_mut(),
143+
SIGSTKSZ + page_size(),
144+
PROT_READ | PROT_WRITE,
145+
MAP_PRIVATE | MAP_ANON,
146+
-1,
147+
0,
148+
);
142149
if stackp == MAP_FAILED {
143150
panic!("failed to allocate an alternative stack");
144151
}
145-
stackp
152+
let guard_result = libc::mprotect(stackp, page_size(), PROT_NONE);
153+
if guard_result != 0 {
154+
panic!("failed to set up alternative stack guard page");
155+
}
156+
stackp.add(page_size())
146157
}
147158

148159
#[cfg(any(
@@ -190,7 +201,9 @@ mod imp {
190201
ss_size: SIGSTKSZ,
191202
};
192203
sigaltstack(&stack, ptr::null_mut());
193-
munmap(handler._data, SIGSTKSZ);
204+
// We know from `get_stackp` that the alternate stack we installed is part of a mapping
205+
// that started one page earlier, so walk back a page and unmap from there.
206+
munmap(handler._data.sub(page_size()), SIGSTKSZ + page_size());
194207
}
195208
}
196209
}

0 commit comments

Comments
 (0)