aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorm <m@pop-os.localdomain>2022-02-11 15:28:36 +0100
committerm <m@pop-os.localdomain>2022-02-11 15:28:36 +0100
commitbd8d6a8342914974ca163fa75db0562d181f6d27 (patch)
tree0c7570d9bbec078ca4910aeff96122582c493e99 /lib/std/debug.zig
parente1a535360fb9ed08fc48018571b9702ab12a5876 (diff)
downloadzig-bd8d6a8342914974ca163fa75db0562d181f6d27.tar.gz
zig-bd8d6a8342914974ca163fa75db0562d181f6d27.zip
std: validate frame-pointer address in stack walking
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 69a68faad6..be47985041 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -424,6 +424,28 @@ pub const StackIterator = struct {
return address;
}
+ fn isValidMemory(address: u64) bool {
+ if (native_os != .windows) {
+ var res = true;
+ const length = 2 * mem.page_size;
+ const aligned_address = address & ~@intCast(u64, (mem.page_size - 1));
+ const aligned_memory = @intToPtr([*]align(mem.page_size) u8, aligned_address)[0..length];
+
+ os.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
+ switch (err) {
+ os.MSyncError.UnmappedMemory => {
+ res = false;
+ },
+ else => unreachable,
+ }
+ };
+ return res;
+ } else {
+ // TODO: Using windows memory API check if a page is mapped
+ return true;
+ }
+ }
+
fn next_internal(self: *StackIterator) ?usize {
const fp = if (comptime native_arch.isSPARC())
// On SPARC the offset is positive. (!)
@@ -432,7 +454,7 @@ pub const StackIterator = struct {
math.sub(usize, self.fp, fp_offset) catch return null;
// Sanity check.
- if (fp == 0 or !mem.isAligned(fp, @alignOf(usize)))
+ if (fp == 0 or !mem.isAligned(fp, @alignOf(usize)) or !isValidMemory(fp))
return null;
const new_fp = math.add(usize, @intToPtr(*const usize, fp).*, fp_bias) catch return null;