From f928e60d41314a9aad2d9629114bb3ae57f51096 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 3 Apr 2024 23:14:52 +0900 Subject: [PATCH] Check if a fatal signal is from kernel On Linux, `siginfo_t` uses a union for each `si_code`, and the field corresponding to `si_pid` does not belong to the `_sigfault` field for SIGSEGV. It actually overlaps the `si_addr` field, which is usually non-zero on stack overflow. https://github.com/ruby/ruby/pull/10201#issuecomment-2034723244 --- signal.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/signal.c b/signal.c index 636574ba07..48b0d4488e 100644 --- a/signal.c +++ b/signal.c @@ -867,16 +867,19 @@ check_stack_overflow(int sig, const void *addr) } } # endif + # ifdef _WIN32 # define CHECK_STACK_OVERFLOW() check_stack_overflow(sig, 0) # else # define FAULT_ADDRESS info->si_addr # ifdef USE_UCONTEXT_REG -# define CHECK_STACK_OVERFLOW() (info->si_pid ? (void)0 : check_stack_overflow(sig, (uintptr_t)FAULT_ADDRESS, ctx)) +# define CHECK_STACK_OVERFLOW_() check_stack_overflow(sig, (uintptr_t)FAULT_ADDRESS, ctx) # else -# define CHECK_STACK_OVERFLOW() (info->si_pid ? (void)0 : check_stack_overflow(sig, FAULT_ADDRESS)) +# define CHECK_STACK_OVERFLOW_() check_stack_overflow(sig, FAULT_ADDRESS) # endif # define MESSAGE_FAULT_ADDRESS " at %p", FAULT_ADDRESS +# define SIGNAL_FROM_USER_P() ((info)->si_code == SI_USER) +# define CHECK_STACK_OVERFLOW() (SIGNAL_FROM_USER_P() ? (void)0 : CHECK_STACK_OVERFLOW_()) # endif #else # define CHECK_STACK_OVERFLOW() (void)0