From 96355f50aa468b2ffc04589ea2b8573619ab205c Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 23 Jan 2023 09:10:24 -0800 Subject: absl: harden stack bounds check Ensure that we know both real low and high stack bounds when relying on the stack bounds check. PiperOrigin-RevId: 504003431 Change-Id: I8f6e6b75f5edff233d3cf80285f81b53f9080a0f --- absl/debugging/internal/stacktrace_x86-inl.inc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc index ada2628d..7b26464e 100644 --- a/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/absl/debugging/internal/stacktrace_x86-inl.inc @@ -267,12 +267,20 @@ static void **NextStackFrame(void **old_fp, const void *uc, // guessed frame pointers incorrectly and now risk a paging fault // dereferencing a wrong frame pointer. Or maybe not because large frames // are possible as well. The main stack is assumed to be readable, - // so we assume the large frame is legit if we know the stack bounds and are - // within the stack. - if (new_fp_u - old_fp_u > kMaxFrameBytes && - (stack_high == kUnknownStackEnd || - !(stack_low < new_fp_u && new_fp_u <= stack_high))) { - return nullptr; + // so we assume the large frame is legit if we know the real stack bounds + // and are within the stack. + if (new_fp_u - old_fp_u > kMaxFrameBytes) { + if (stack_high < kUnknownStackEnd && + static_cast(getpagesize()) < stack_low) { + // Stack bounds are known. + if (!(stack_low < new_fp_u && new_fp_u <= stack_high)) { + // new_fp_u is not within the known stack. + return nullptr; + } + } else { + // Stack bounds are unknown, prefer truncated stack to possible crash. + return nullptr; + } } if (stack_low < old_fp_u && old_fp_u <= stack_high) { // Old BP was in the expected stack region... -- cgit v1.2.3