mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
std: Different thread stack allocation for NetBSD
* NetBSD is stricter than other OSs and doesn't allow mprotect to mark a non-accessible region as RW * Fix mprotect call over the whole stack, oops
This commit is contained in:
parent
cda73c3c18
commit
09a5f172f8
@ -292,32 +292,69 @@ pub const Thread = struct {
|
||||
l += tls_img.alloc_size;
|
||||
}
|
||||
}
|
||||
break :blk l;
|
||||
// Round the size to the page size.
|
||||
break :blk mem.alignForward(l, mem.page_size);
|
||||
};
|
||||
// Map the whole stack with no rw permissions to avoid committing the
|
||||
// whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mem.alignForward(mmap_len, mem.page_size),
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
const mmap_slice = mem: {
|
||||
if (std.Target.current.os.tag != .netbsd) {
|
||||
// Map the whole stack with no rw permissions to avoid
|
||||
// committing the whole region right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_NONE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Map everything but the guard page as rw
|
||||
os.mprotect(
|
||||
mmap_slice[guard_end_offset..],
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
} else {
|
||||
// NetBSD mprotect is very strict and doesn't allow to "upgrade"
|
||||
// a PROT_NONE mapping to a RW one so let's allocate everything
|
||||
// right away
|
||||
const mmap_slice = os.mmap(
|
||||
null,
|
||||
mmap_len,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
os.MAP_PRIVATE | os.MAP_ANONYMOUS,
|
||||
-1,
|
||||
0,
|
||||
) catch |err| switch (err) {
|
||||
error.MemoryMappingNotSupported => unreachable,
|
||||
error.AccessDenied => unreachable,
|
||||
error.PermissionDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
errdefer os.munmap(mmap_slice);
|
||||
|
||||
// Remap the guard page with no permissions
|
||||
os.mprotect(
|
||||
mmap_slice[0..guard_end_offset],
|
||||
os.PROT_NONE,
|
||||
) catch |err| switch (err) {
|
||||
error.AccessDenied => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
break :mem mmap_slice;
|
||||
}
|
||||
};
|
||||
|
||||
const mmap_addr = @ptrToInt(mmap_slice.ptr);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user