diff options
| author | m <m@pop-os.localdomain> | 2022-02-11 15:28:36 +0100 |
|---|---|---|
| committer | m <m@pop-os.localdomain> | 2022-02-11 15:28:36 +0100 |
| commit | bd8d6a8342914974ca163fa75db0562d181f6d27 (patch) | |
| tree | 0c7570d9bbec078ca4910aeff96122582c493e99 /lib/std/debug.zig | |
| parent | e1a535360fb9ed08fc48018571b9702ab12a5876 (diff) | |
| download | zig-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.zig | 24 |
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; |
