Date: Thu, 19 Apr 2001 07:53:37 -0700 (PDT) From: fwkg7679@mb.infoweb.ne.jp To: freebsd-gnats-submit@FreeBSD.org Subject: kern/26705: P_ALTSTACK in proc::p_flag isn't copied to the child process on fork(2) Message-ID: <200104191453.f3JErb999480@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 26705 >Category: kern >Synopsis: P_ALTSTACK in proc::p_flag isn't copied to the child process on fork(2) >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Apr 19 08:00:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: KUROSAWA Takahiro >Release: FreeBSD 4-STABLE and FreeBSD 5.0-CURRENT >Organization: >Environment: FreeBSD amdk6 5.0-CURRENT FreeBSD 5.0-CURRENT #15: Sun Apr 15 23:59:14 JST 2001 kurosawa@amdk6:/.world/src/sys/compile/AMDK6ACPI i386 >Description: P_ALTSTACK in struct proc::p_flag should be copied to the child process on fork(2), but actually it isn't. The setting of the signal stack by sigaltstack(2) on the parent process is not inherited to the child process on fork(2) as a result of this problem. This causes a fatal problem on Pthreads applications that uses fork(2). The manpage of sigaction(2) states that the signal stack is inherited to the child process but the signal stack isn't inherited on 4-STABLE and 5-CURRENT. On 3-STABLE systems, the signal stack seems to be inherited to the child process correctly. For more information, please read these mails in -current list: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=473293+0+archive/2001/freebsd-current/20010318.freebsd-current http://docs.freebsd.org/cgi/getmsg.cgi?fetch=332928+0+archive/2001/freebsd-current/20010304.freebsd-current >How-To-Repeat: Run the following program and compare the result on other operatiing systems. At least, FreeBSD 3-STABLE and NetBSD 1.5 correctly handles the setting of the signal stack. #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; } >Fix: Apply this patch to kernel sources: diff -ur src.org/sys/kern/kern_fork.c src/sys/kern/kern_fork.c --- src.org/sys/kern/kern_fork.c Mon Feb 19 00:41:10 2001 +++ src/sys/kern/kern_fork.c Thu Apr 19 11:34:34 2001 @@ -434,7 +434,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) diff -ur src.org/sys/kern/kern_sig.c src/sys/kern/kern_sig.c --- src.org/sys/kern/kern_sig.c Thu Feb 22 14:15:04 2001 +++ src/sys/kern/kern_sig.c Thu Apr 19 11:35:03 2001 @@ -433,6 +433,7 @@ p->p_sigstk.ss_flags = SS_DISABLE; p->p_sigstk.ss_size = 0; p->p_sigstk.ss_sp = 0; + p->p_flag &= ~P_ALTSTACK; /* * Reset no zombies if child dies flag as Solaris does. */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104191453.f3JErb999480>