NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/57946: longjmp fails to restore stack first before restoring signal mask on most architectures
>Number: 57946
>Category: lib
>Synopsis: longjmp fails to restore stack first before restoring signal mask on most architectures
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 19 04:25:01 +0000 2024
>Originator: Taylor R Campbell
>Release: current, 10, 9, 8, ...
>Organization:
The NetBSD FoundaSQUIRREL
>Environment:
arm, hppa, i386, ia64, mips, sh3, sparc, sparc64, amd64
>Description:
longjmp(3) is supposed to restore various saved state, including registers, stack pointer, and signal mask, and then come flying out of the corresponding call to setjmp(3).
However, if a signal is already pending, and longjmp(3) restores the signal mask first, the signal handler will be triggered before the stack pointer has been restored -- which means if the signal handler itself called longjmp, it may recursively enter on the signal stack rather than the original stack.
>How-To-Repeat:
// https://www.openwall.com/lists/musl/2024/02/18/16
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
static volatile long cnt = 1000000;
jmp_buf jb;
void handle(int s)
{
volatile int x;
if (cnt % 1000 == 0) printf("%p\n", &x);
if (!cnt--) return;
raise(s);
longjmp(jb, 1);
}
int main()
{
if (setjmp(jb)) return 0;
signal(SIGALRM, handle);
raise(SIGALRM);
}
>Fix:
Restore signal mask last in longjmp (and in siglongjmp for the savemask case).
Home |
Main Index |
Thread Index |
Old Index