NetBSD Problem Report #57946
From www@netbsd.org Mon Feb 19 04:24:45 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 97E361A9239
for <gnats-bugs@gnats.NetBSD.org>; Mon, 19 Feb 2024 04:24:45 +0000 (UTC)
Message-Id: <20240219042444.458CA1A923A@mollari.NetBSD.org>
Date: Mon, 19 Feb 2024 04:24:44 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: longjmp fails to restore stack first before restoring signal mask on most architectures
X-Send-Pr-Version: www-1.0
>Number: 57946
>Notify-List: uwe@NetBSD.org
>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: analyzed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 19 04:25:01 +0000 2024
>Closed-Date:
>Last-Modified: Thu Apr 04 00:50:03 +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).
>Release-Note:
>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src
Date: Mon, 19 Feb 2024 04:30:39 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 04:30:39 UTC 2024
Modified Files:
src/distrib/sets/lists/debug: mi
src/distrib/sets/lists/tests: mi
src/tests/lib/libc/setjmp: Makefile
Added Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3): Add test for PR lib/57946.
To generate a diff of this commit:
cvs rdiff -u -r1.424 -r1.425 src/distrib/sets/lists/debug/mi
cvs rdiff -u -r1.1305 -r1.1306 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.2 -r1.3 src/tests/lib/libc/setjmp/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 04:33:21 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 04:33:21 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3): Paranoia: more error checking in PR lib/57946 test.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->analyzed
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Mon, 19 Feb 2024 04:40:30 +0000
State-Changed-Why:
problem analyzed
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 12:29:48 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 12:29:48 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3): Test signal mask vs stack restore with siglongjmp too.
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 12:41:19 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 12:41:19 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3) t_sigstack: Print which entry failed.
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 12:41:27 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 12:41:27 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3) t_sigstack: Note aarch64 seems to DTRT.
But only by code inspection; it appears to have another problem: on
re-entry, the signal handler is called on the normal stack, not on
the alternate signal stack.
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 13:34:48 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 13:34:48 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3) t_sigstack: Use a sigaltstack per handler entry.
longjmp evidently doesn't reset the state of whether the process is
executing on the alternate signal stack. So when we re-enter the
signal handler, the alternate stack appears to be still in use, and
the system chooses the original stack for the second call to the
signal handler -- which trips our assertion asking to verify that the
signal handler is always using an alternate stack.
Not strictly necessary for the signal handler to use an alternate
stack on re-entry, but this makes it clearer that the signal handler
itself is always using the alternate stack so we can verify that the
interrupted code is _not_ in the signal handler.
With this change, the test now passes on aarch64.
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src/tests/lib/libc/setjmp
Date: Mon, 19 Feb 2024 19:43:27 +0000
Module Name: src
Committed By: riastradh
Date: Mon Feb 19 19:43:27 UTC 2024
Modified Files:
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
longjmp(3) t_sigstack: Fix fencepost error.
Extremely unlikely to cause trouble, but let's just turn that into
`never' to keep it easier for readers.
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src
Date: Thu, 4 Apr 2024 00:46:30 +0000
Module Name: src
Committed By: riastradh
Date: Thu Apr 4 00:46:30 UTC 2024
Modified Files:
src/lib/libc/arch/x86_64/gen: __setjmp14.S __sigsetjmp14.S
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
amd64 longjmp: Restore stack first, then signal mask.
Otherwise, a pending signal may be delivered on the wrong stack when
we restore the signal mask.
While here:
- Tidy the code a little bit.
- Sprinkle comments to explain what's going on.
- Use `xorl %eXX,%eXX' instead of `xorq %rXX,%rXX'.
=> Same effect, one byte shorter, breaks dep chain on more uarches.
- Use forward branches for statically predicted not-taken.
=> val==0 is unlikely in longjmp
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/x86_64/gen/__setjmp14.S \
src/lib/libc/arch/x86_64/gen/__sigsetjmp14.S
cvs rdiff -u -r1.7 -r1.8 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/57946 CVS commit: src
Date: Thu, 4 Apr 2024 00:46:42 +0000
Module Name: src
Committed By: riastradh
Date: Thu Apr 4 00:46:42 UTC 2024
Modified Files:
src/lib/libc/arch/i386/gen: setjmp.S sigsetjmp.S
src/tests/lib/libc/setjmp: t_sigstack.c
Log Message:
i386 longjmp: Restore stack first, then signal mask.
Otherwise, a pending signal may be delivered on the wrong stack when
we restore the signal mask.
While here:
- Tidy the code a little bit.
- Sprinkle comments to explain what's going on.
- Use forward branches for statically predicted not-taken.
=> val==0 is unlikely in longjmp
PR lib/57946
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/lib/libc/arch/i386/gen/setjmp.S
cvs rdiff -u -r1.18 -r1.19 src/lib/libc/arch/i386/gen/sigsetjmp.S
cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libc/setjmp/t_sigstack.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.