NetBSD Problem Report #50428

From www@NetBSD.org  Sat Nov 14 10:09:06 2015
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 07CE0A6552
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 14 Nov 2015 10:09:06 +0000 (UTC)
Message-Id: <20151114100904.11EC6A6554@mollari.NetBSD.org>
Date: Sat, 14 Nov 2015 10:09:04 +0000 (UTC)
From: okuyama@flex.phys.tohoku.ac.jp
Reply-To: okuyama@flex.phys.tohoku.ac.jp
To: gnats-bugs@NetBSD.org
Subject: support SA_RESTORER flag for rt_sigaction(2) in Linux emulation
X-Send-Pr-Version: www-1.0

>Number:         50428
>Category:       kern
>Synopsis:       support SA_RESTORER flag for rt_sigaction(2) in Linux emulation
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Nov 14 10:10:00 +0000 2015
>Closed-Date:    Sat Nov 14 23:33:31 +0000 2015
>Last-Modified:  Wed Dec 16 08:35:01 +0000 2015
>Originator:     Rin Okuyama
>Release:        7.99.21
>Organization:
Department of Physics, Tohoku University
>Environment:
NetBSD XXX 7.99.21 NetBSD 7.99.21 (GENERIC) #0: Sat Nov 14 16:22:15 JST 2015  root@XXX:XXX i386
>Description:
On Linux, SA_RESTORER flag for rt_sigaction(2) indicates that a signal
trampoline is provided by userland (usually by libc). Until now, this
flag has not been supported on ports other than amd64, which causes
EINVAL with some application on, e.g., i386.

The patch attached below enables SA_RESTORER flag on ports where Linux
supports it: arm, i386, and powerpc. It also fixes incorrect prototype
definitions of signal handler and trampoline on amd64.

Note that SA_RESTORER is not supported on alpha. On mips, it is no
longer supported by kernel, as it has never been used by libc (they
said).

Also note that I've checked this patch only on amd64 and i386.
>How-To-Repeat:
On i386, rt_sigaction(2) fails with EINVAL:

% ktrace /emul/linux/bin/bash
bash-4.2$ exit
% kdump
...
  2515   2515 bash     CALL  rt_sigaction(SIGCHLD,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGCHLD,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGINT,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGINT,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGQUIT,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGQUIT,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGTERM,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGTERM,0xbfbff074,0xbfbff100,8)
  2515   2515 bash     RET   rt_sigaction 0
  2515   2515 bash     CALL  rt_sigaction(SIGHUP,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     NAMI  "/stand/i386/7.99.21/modules/compat/compat.kmod"
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGINT,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGILL,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGTRAP,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGABRT,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGFPE,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGBUS,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGSEGV,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGSYS,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGPIPE,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGALRM,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGTERM,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGXCPU,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGXFSZ,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGVTALRM,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGUSR1,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigaction(SIGUSR2,0xbfbff064,0xbfbff0f0,8)
  2515   2515 bash     RET   rt_sigaction -1 errno -22 Invalid argument
  2515   2515 bash     CALL  rt_sigprocmask(0,0,0x80ea340,8)
  2515   2515 bash     RET   rt_sigprocmask 0
...

After applying the patch below, rt_sigaction(2) works fine:

% ktrace /emul/linux/bash
bash-4.2$ exit
% kdump
...
   557    557 bash     CALL  rt_sigaction(SIGCHLD,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGCHLD,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGINT,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGINT,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGQUIT,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGQUIT,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGTERM,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGTERM,0xbfbff5a4,0xbfbff630,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGHUP,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGINT,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGILL,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGTRAP,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGABRT,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGFPE,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGBUS,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGSEGV,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGSYS,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGPIPE,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGALRM,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGTERM,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGXCPU,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGXFSZ,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGVTALRM,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGUSR1,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigaction(SIGUSR2,0xbfbff594,0xbfbff620,8)
   557    557 bash     RET   rt_sigaction 0
   557    557 bash     CALL  rt_sigprocmask(0,0,0x80ea340,8)
   557    557 bash     RET   rt_sigprocmask 0
...
>Fix:
--- ./src/sys/compat/linux/arch/alpha/linux_signal.h.orig	2015-11-14 15:17:42.000000000 +0900
+++ ./src/sys/compat/linux/arch/alpha/linux_signal.h	2015-11-14 15:57:34.000000000 +0900
@@ -92,13 +92,12 @@
 #define LINUX_SA_RESETHAND	0x00000010
 #define LINUX_SA_NOCLDWAIT	0x00000020
 #define LINUX_SA_SIGINFO	0x00000040
-#define LINUX_SA_RESTORER	0x04000000

 #define LINUX_SA_NOMASK		LINUX_SA_NODEFER
 #define LINUX_SA_ONESHOT	LINUX_SA_RESETHAND
 #define LINUX_SA_INTERRUPT	0x20000000	/* Ignore this */

-#define LINUX_SA_ALLBITS	0x2400007f
+#define LINUX_SA_ALLBITS	0x2000007f

 #define LINUX_SIG_BLOCK		1
 #define LINUX_SIG_UNBLOCK	2
--- ./src/sys/compat/linux/arch/amd64/linux_signal.h.orig	2015-11-14 15:40:06.000000000 +0900
+++ ./src/sys/compat/linux/arch/amd64/linux_signal.h	2015-11-14 15:56:58.000000000 +0900
@@ -103,24 +103,24 @@

 /* struct old_sigaction32 in Linux; uses a 32 bit pointer for handlers */
 struct linux_compat_old_sigaction { 
-	int linux_sa_handler;
+	linux_handler_t linux_sa_handler;
 	linux_old_sigset_t linux_sa_mask;
 	unsigned int linux_sa_flags;
-	int linux_sa_restorer;
+	void (*linux_sa_restorer)(void);
 };

 /* Dummy declaration to avoid errors, unused */
 struct linux_old_sigaction { 
 	linux_handler_t linux_sa_handler;
 	unsigned long linux_sa_flags;
-	linux_handler_t linux_sa_restorer;
+	void (*linux_sa_restorer)(void);
 	linux_sigset_t linux_sa_mask;
 };

 struct linux_sigaction {
 	linux_handler_t linux_sa_handler;
 	unsigned long linux_sa_flags;
-	linux_handler_t linux_sa_restorer;
+	void (*linux_sa_restorer)(void);
 	linux_sigset_t linux_sa_mask;
 };

--- ./src/sys/compat/linux/arch/mips/linux_signal.h.orig	2015-11-14 15:17:42.000000000 +0900
+++ ./src/sys/compat/linux/arch/mips/linux_signal.h	2015-11-14 15:59:39.000000000 +0900
@@ -104,15 +104,14 @@
 #define LINUX_SA_NOCLDSTOP	0x00000001
 #define LINUX_SA_SIGINFO	0x00000008
 #define LINUX_SA_NOCLDWAIT	0x00010000
-#define LINUX_SA_RESTORER	0x04000000
 #define LINUX_SA_ONSTACK	0x08000000
 #define LINUX_SA_RESTART	0x10000000
-#define LINUX_SA_INTERRUPT	0x20000000
 #define LINUX_SA_NODEFER	0x40000000
 #define LINUX_SA_RESETHAND	0x80000000
 #define LINUX_SA_NOMASK		LINUX_SA_NODEFER
 #define LINUX_SA_ONESHOT	LINUX_SA_RESETHAND
-#define LINUX_SA_ALLBITS	0xfc010009 /* XXX from i386, not in mips. */
+#define LINUX_SA_ALLBITS	0xd8010009
+/* XXX LINUX_SA_RESTORER has been deprecated; not used any version of glibc */

 #define	LINUX_MINSIGSTKSZ	2048

--- ./src/sys/compat/linux/common/linux_signal.c.orig	2015-11-14 15:17:42.000000000 +0900
+++ ./src/sys/compat/linux/common/linux_signal.c	2015-11-14 16:50:48.000000000 +0900
@@ -331,7 +331,7 @@
 	int error, sig;
 	void *tramp = NULL;
 	int vers = 0;
-#if defined __amd64__
+#ifdef LINUX_SA_RESTORER
 	struct sigacts *ps = l->l_proc->p_sigacts;
 #endif

@@ -354,11 +354,10 @@
 		sigemptyset(&obsa.sa_mask);
 		obsa.sa_flags = 0;
 	} else {
-#if defined __amd64__
-		if (nlsa.linux_sa_flags & LINUX_SA_RESTORER) {
-			if ((tramp = nlsa.linux_sa_restorer) != NULL)
-				vers = 2; /* XXX arch dependent */
-		}
+#ifdef LINUX_SA_RESTORER
+		if ((nlsa.linux_sa_flags & LINUX_SA_RESTORER) &&
+		    (tramp = nlsa.linux_sa_restorer) != NULL)
+				vers = 2;
 #endif

 		error = sigaction1(l, linux_to_native_signo[sig],
@@ -371,7 +370,7 @@
 	if (SCARG(uap, osa)) {
 		native_to_linux_sigaction(&olsa, &obsa);

-#if defined __amd64__
+#ifdef LINUX_SA_RESTORER
 		if (ps->sa_sigdesc[sig].sd_vers != 0) {
 			olsa.linux_sa_restorer = ps->sa_sigdesc[sig].sd_tramp;
 			olsa.linux_sa_flags |= LINUX_SA_RESTORER;

>Release-Note:

>Audit-Trail:
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50428 CVS commit: src/sys/compat/linux
Date: Sat, 14 Nov 2015 08:29:35 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Sat Nov 14 13:29:35 UTC 2015

 Modified Files:
 	src/sys/compat/linux/arch/alpha: linux_signal.h
 	src/sys/compat/linux/arch/amd64: linux_signal.h
 	src/sys/compat/linux/arch/mips: linux_signal.h
 	src/sys/compat/linux/common: linux_signal.c

 Log Message:
 PR/50428: Rin Okuyama: support SA_RESTORER flag for rt_sigaction(2) in the
 ports that support it.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.10 src/sys/compat/linux/arch/alpha/linux_signal.h
 cvs rdiff -u -r1.4 -r1.5 src/sys/compat/linux/arch/amd64/linux_signal.h
 cvs rdiff -u -r1.13 -r1.14 src/sys/compat/linux/arch/mips/linux_signal.h
 cvs rdiff -u -r1.76 -r1.77 src/sys/compat/linux/common/linux_signal.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: PR/50428 CVS commit: src/sys/compat/linux
Date: Sat, 14 Nov 2015 23:22:55 +0900

 Confirmed. Thank you very much for your rapid response.

State-Changed-From-To: open->closed
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Sat, 14 Nov 2015 23:33:31 +0000
State-Changed-Why:
Confirmed fixed! Thanks for the quick feedback.


From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: gnats-bugs@NetBSD.org, Christos Zoulas <christos@netbsd.org>
Cc: 
Subject: Re: PR/50428 CVS commit: src/sys/compat/linux
Date: Wed, 16 Dec 2015 17:31:25 +0900

 Triggered by this change, an uninitialized-variable defect, CID 980928,
 was found by Coverity.

   http://mail-index.netbsd.org/coverity-updates/2015/11/23/msg000196.html

 Please apply the attached patch. I've tested it on i386 and amd64.

 --- src/sys/compat/linux/common/linux_signal.c.orig	2015-12-04 07:07:37.000000000 +0900
 +++ src/sys/compat/linux/common/linux_signal.c	2015-12-04 07:10:47.000000000 +0900
 @@ -355,7 +355,8 @@
  		obsa.sa_flags = 0;
  	} else {
  #ifdef LINUX_SA_RESTORER
 -		if ((nlsa.linux_sa_flags & LINUX_SA_RESTORER) &&
 +		if (SCARG(uap, nsa) &&
 +		    (nlsa.linux_sa_flags & LINUX_SA_RESTORER) &&
  		    (tramp = nlsa.linux_sa_restorer) != NULL)
  				vers = 2;
  #endif

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.