NetBSD Problem Report #58268
From www@netbsd.org Mon May 20 04:29:57 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 21B001A9264
for <gnats-bugs@gnats.NetBSD.org>; Mon, 20 May 2024 04:29:57 +0000 (UTC)
Message-Id: <20240520042955.ABC6F1A9265@mollari.NetBSD.org>
Date: Mon, 20 May 2024 04:29:55 +0000 (UTC)
From: noah@leadboat.com
Reply-To: noah@leadboat.com
To: gnats-bugs@NetBSD.org
Subject: execve() discards pending signal
X-Send-Pr-Version: www-1.0
>Number: 58268
>Category: kern
>Synopsis: execve() discards pending signal
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 20 04:30:00 +0000 2024
>Originator: Noah Misch
>Release: 9.2, 9.4, 10.0
>Organization:
>Environment:
NetBSD 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/execve.html says the
new process inherits "pending signal". Per the below test program, a signal
pending before execve() is neither delivered nor pending after execve(). The
test program observed this in NetBSD 9.2, 9.4 and 10.0. The other operating
systems I tested keep the signal pending; the test program header comment lists
them.
[non-essential background info] I discovered this in the context of
https://github.com/cpan-authors/IPC-Run/issues/175, where an IPC::Run test case
can make kill(KID, SIGTERM) overlap KID running exec(). The IPC::Run test never
runs kill() before exec(), always during exec() or after exec(). Hence, it's
different from the below C program, which makes the signal pending before
exec(). The IPC::Run test case was stable on NetBSD until NetBSD 10.0.
Starting with NetBSD 10.0, the IPC::Run SIGTERM is usually lost. Perhaps NetBSD
10.0 expanded the ability of actions to interrupt exec(). That's fine.
>How-To-Repeat:
/*
* Return value:
* 1 if sigprocmask(SIG_UNBLOCK) returns w/ SIGTERM pending
* 2 if sigprocmask(SIG_UNBLOCK) returns w/ SIGTERM *not* pending
* 90 if exec fails
*
* AIX 7300-01-02-2320: returns 1 always. Compiling with -DREBLOCK makes it die
* to SIGTERM always.
*
* Same as AIX:
* Darwin 21.6.0
* FreeBSD 14.0-release-p6
* Linux 6.7.12-amd64
* OpenBSD 7.5
* Solaris 11.4.68.164.2
*
* NetBSD 10.0, 9.4, 9.2: returns 2 always.
*
* Linux 3.10.0-1160.99.1.el7.x86_64: Dies to SIGTERM about half the time,
* returning 1 the other half. Compiling with -DREBLOCK makes it die to SIGTERM
* always.
*/
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
sigset_t set;
if (argc == 1)
{
char *cmd[] = { argv[0], "anything", (char *)0 };
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigprocmask(SIG_BLOCK, &set, NULL);
raise(SIGTERM);
execv(argv[0], cmd);
return 90;
}
else
{
char msg[] = "reached write()\n";
#if REBLOCK
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigprocmask(SIG_BLOCK, &set, NULL);
#endif
write(2, msg, sizeof(msg) - 1);
sigprocmask(SIG_UNBLOCK, &set, NULL);
sigpending(&set);
return sigismember(&set, SIGTERM) ? 1 : 2;
}
}
>Fix:
not known
(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.