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

NetBSD Home
NetBSD PR Database Search

(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.