Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 02 Mar 2001 22:34:18 +0900
From:      KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
To:        current@freebsd.org
Subject:   sigaltstack(2) setting not inherited by the child process
Message-ID:  <200103021332.WAA20909@mf003.infoweb.ne.jp>

next in thread | raw e-mail | index | archive | help
--Multipart_Fri_Mar__2_22:34:18_2001-1
Content-Type: text/plain; charset=US-ASCII

The sigaction(2) manpage states that the signal stack is inherited by
the child after fork(2), but the signal stack is not inherited in fact.

The attached test program checks if the sigaltstack(2) setting is
inherited by the child or not.
The result of the program is:
  original: sp=0x0 size=0 flags=4
   changed: sp=0x8049a20 size=1048576 flags=0
     child: sp=0x8049a20 size=1048576 flags=4    <- flags: 4
    parent: sp=0x8049a20 size=1048576 flags=0

but it should be:
  original: sp=0x0 size=0 flags=4
   changed: sp=0x8049a20 size=1048576 flags=0
     child: sp=0x8049a20 size=1048576 flags=0    <- flags: 0
    parent: sp=0x8049a20 size=1048576 flags=0

The parent had cleared the SS_DISABLE flag of ss_flags (in struct
sigaltstack) and forked the child, but SS_DISABLE is set on the child.

The following patch against sys/kern/kern_fork.c fixes this problem:

Index: sys/kern/kern_fork.c
===================================================================
RCS file: /usr/local/share/cvsup/cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.103
diff -u -r1.103 kern_fork.c
--- sys/kern/kern_fork.c	2001/02/28 02:53:43	1.103
+++ sys/kern/kern_fork.c	2001/03/02 12:45:40
@@ -461,7 +461,7 @@
 	 * Preserve some more flags in subprocess.  P_PROFIL has already
 	 * been preserved.
 	 */
-	p2->p_flag |= p1->p_flag & P_SUGID;
+	p2->p_flag |= p1->p_flag & (P_SUGID | P_ALTSTACK);
 	if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
 		p2->p_flag |= P_CONTROLT;
 	if (flags & RFPPWAIT)


--Multipart_Fri_Mar__2_22:34:18_2001-1
Content-Type: text/plain; charset=US-ASCII

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <assert.h>

#define ALTSTACKSIZE	(1024 * 1024)
static u_int64_t	altstack[ALTSTACKSIZE / sizeof(u_int64_t)];

static void
print_sigstack(char *info)
{
	struct sigaltstack		ss;
	int				ret;

	ret = sigaltstack(NULL, &ss);
	if (ret < 0) {
		perror("sigaltstack");
		exit(1);
	}
	printf("%10s: sp=%p size=%d flags=%x\n",
	       info, ss.ss_sp, ss.ss_size, ss.ss_flags);
	fflush(stdout);
}

int
main(int argc, char *argv[])
{
	struct sigaltstack		ss;
	pid_t				pid;
	int				ret;

	print_sigstack("original");

	ss.ss_sp = (char *)altstack;
	ss.ss_size = sizeof(altstack);
	ss.ss_flags = 0;
	ret = sigaltstack(&ss, NULL);
	if (ret < 0) {
		perror("sigaltstack");
		exit(1);
	}
	print_sigstack("changed");

	pid = fork();
	if (pid < 0) {
		perror("fork");
		exit(1);
	}
	if (pid == 0) {
		print_sigstack("child");
		exit(0);
	}
	wait(NULL);
	print_sigstack("parent");

	return 0;
}

--Multipart_Fri_Mar__2_22:34:18_2001-1--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103021332.WAA20909>