Konstantin Belousov
2015-Aug-29 13:41 UTC
Latest stable (r287104) bash leaves zombies on exit
On Sat, Aug 29, 2015 at 03:01:38PM +0200, Jilles Tjoelker wrote:> Looks good to me, except that I think a vforked child (in system() and > posix_spawn*()) should use the system calls and not libthr's wrappers. > This reduces the probability of weird things happening between vfork and > exec, and also avoids an unexpected error when > posix_spawnattr_setsigdefault()'s mask contains SIGTHR.Thank you for the review, I agree with the note about vfork. Updated patch is below. Also, I removed the PIC_PROLOGUE from the i386 setjmp, it has no use after the plt calls are removed. diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S index c26f52f..826220e 100644 --- a/lib/libc/amd64/gen/setjmp.S +++ b/lib/libc/amd64/gen/setjmp.S @@ -55,7 +55,7 @@ ENTRY(setjmp) movq $0,%rsi /* (sigset_t*)set */ leaq 72(%rcx),%rdx /* 9,10; (sigset_t*)oset */ /* stack is 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask popq %rdi movq %rdi,%rcx movq 0(%rsp),%rdx /* retval */ @@ -82,7 +82,7 @@ ENTRY(__longjmp) leaq 72(%rdx),%rsi /* (sigset_t*)set */ movq $0,%rdx /* (sigset_t*)oset */ subq $0x8,%rsp /* make the stack 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask addq $0x8,%rsp popq %rsi popq %rdi /* jmpbuf */ diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S index 9a20556..1e8e77c 100644 --- a/lib/libc/amd64/gen/sigsetjmp.S +++ b/lib/libc/amd64/gen/sigsetjmp.S @@ -63,7 +63,7 @@ ENTRY(sigsetjmp) movq $0,%rsi /* (sigset_t*)set */ leaq 72(%rcx),%rdx /* 9,10 (sigset_t*)oset */ /* stack is 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask popq %rdi 2: movq %rdi,%rcx movq 0(%rsp),%rdx /* retval */ @@ -91,7 +91,7 @@ ENTRY(__siglongjmp) leaq 72(%rdx),%rsi /* (sigset_t*)set */ movq $0,%rdx /* (sigset_t*)oset */ subq $0x8,%rsp /* make the stack 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask addq $0x8,%rsp popq %rsi popq %rdi /* jmpbuf */ diff --git a/lib/libc/compat-43/sigcompat.c b/lib/libc/compat-43/sigcompat.c index 199846f..a8cef1c 100644 --- a/lib/libc/compat-43/sigcompat.c +++ b/lib/libc/compat-43/sigcompat.c @@ -59,7 +59,7 @@ sigvec(signo, sv, osv) } else sap = NULL; osap = osv != NULL ? &osa : NULL; - ret = _sigaction(signo, sap, osap); + ret = __libc_sigaction(signo, sap, osap); if (ret == 0 && osv != NULL) { osv->sv_handler = osa.sa_handler; osv->sv_flags = osa.sa_flags ^ SV_INTERRUPT; @@ -77,7 +77,7 @@ sigsetmask(mask) sigemptyset(&set); set.__bits[0] = mask; - n = _sigprocmask(SIG_SETMASK, &set, &oset); + n = __libc_sigprocmask(SIG_SETMASK, &set, &oset); if (n) return (n); return (oset.__bits[0]); @@ -92,7 +92,7 @@ sigblock(mask) sigemptyset(&set); set.__bits[0] = mask; - n = _sigprocmask(SIG_BLOCK, &set, &oset); + n = __libc_sigprocmask(SIG_BLOCK, &set, &oset); if (n) return (n); return (oset.__bits[0]); @@ -105,7 +105,7 @@ sigpause(int mask) sigemptyset(&set); set.__bits[0] = mask; - return (_sigsuspend(&set)); + return (__libc_sigsuspend(&set)); } int @@ -113,11 +113,11 @@ xsi_sigpause(int sig) { sigset_t set; - if (_sigprocmask(SIG_BLOCK, NULL, &set) == -1) + if (__libc_sigprocmask(SIG_BLOCK, NULL, &set) == -1) return (-1); if (sigdelset(&set, sig) == -1) return (-1); - return (_sigsuspend(&set)); + return (__libc_sigsuspend(&set)); } int @@ -128,7 +128,7 @@ sighold(int sig) sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (-1); - return (_sigprocmask(SIG_BLOCK, &set, NULL)); + return (__libc_sigprocmask(SIG_BLOCK, &set, NULL)); } int @@ -138,7 +138,7 @@ sigignore(int sig) bzero(&sa, sizeof(sa)); sa.sa_handler = SIG_IGN; - return (_sigaction(sig, &sa, NULL)); + return (__libc_sigaction(sig, &sa, NULL)); } int @@ -149,7 +149,7 @@ sigrelse(int sig) sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (-1); - return (_sigprocmask(SIG_UNBLOCK, &set, NULL)); + return (__libc_sigprocmask(SIG_UNBLOCK, &set, NULL)); } void @@ -161,26 +161,26 @@ void sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (SIG_ERR); - if (_sigprocmask(SIG_BLOCK, NULL, &pset) == -1) + if (__libc_sigprocmask(SIG_BLOCK, NULL, &pset) == -1) return (SIG_ERR); if ((__sighandler_t *)disp == SIG_HOLD) { - if (_sigprocmask(SIG_BLOCK, &set, &pset) == -1) + if (__libc_sigprocmask(SIG_BLOCK, &set, &pset) == -1) return (SIG_ERR); if (sigismember(&pset, sig)) return (SIG_HOLD); else { - if (_sigaction(sig, NULL, &psa) == -1) + if (__libc_sigaction(sig, NULL, &psa) == -1) return (SIG_ERR); return (psa.sa_handler); } } else { - if (_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1) + if (__libc_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1) return (SIG_ERR); } bzero(&sa, sizeof(sa)); sa.sa_handler = disp; - if (_sigaction(sig, &sa, &psa) == -1) + if (__libc_sigaction(sig, &sa, &psa) == -1) return (SIG_ERR); if (sigismember(&pset, sig)) return (SIG_HOLD); diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c index 94ba014..051fc28 100644 --- a/lib/libc/db/btree/bt_open.c +++ b/lib/libc/db/btree/bt_open.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> #include "un-namespace.h" +#include "libc_private.h" #include <db.h> #include "btree.h" @@ -401,10 +402,10 @@ tmp(void) } (void)sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); if ((fd = mkostemp(path, O_CLOEXEC)) != -1) (void)unlink(path); - (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, NULL); return(fd); } diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c index d319d98..8040419 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include <assert.h> #endif #include "un-namespace.h" +#include "libc_private.h" #include <db.h> #include "hash.h" @@ -861,10 +862,10 @@ open_temp(HTAB *hashp) /* Block signals; make sure file goes away at process exit. */ (void)sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); if ((hashp->fp = mkostemp(path, O_CLOEXEC)) != -1) (void)unlink(path); - (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); return (hashp->fp != -1 ? 0 : -1); } diff --git a/lib/libc/gen/daemon.c b/lib/libc/gen/daemon.c index b359a87..15c6f4a 100644 --- a/lib/libc/gen/daemon.c +++ b/lib/libc/gen/daemon.c @@ -41,10 +41,10 @@ __FBSDID("$FreeBSD$"); #include <signal.h> #include <unistd.h> #include "un-namespace.h" +#include "libc_private.h" int -daemon(nochdir, noclose) - int nochdir, noclose; +daemon(int nochdir, int noclose) { struct sigaction osa, sa; int fd; @@ -56,7 +56,7 @@ daemon(nochdir, noclose) sigemptyset(&sa.sa_mask); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; - osa_ok = _sigaction(SIGHUP, &sa, &osa); + osa_ok = __libc_sigaction(SIGHUP, &sa, &osa); switch (fork()) { case -1: @@ -74,7 +74,7 @@ daemon(nochdir, noclose) newgrp = setsid(); oerrno = errno; if (osa_ok != -1) - _sigaction(SIGHUP, &osa, NULL); + __libc_sigaction(SIGHUP, &osa, NULL); if (newgrp == -1) { errno = oerrno; diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c index e3124b2..673c760 100644 --- a/lib/libc/gen/posix_spawn.c +++ b/lib/libc/gen/posix_spawn.c @@ -118,15 +118,18 @@ process_spawnattr(const posix_spawnattr_t sa) return (errno); } - /* Set signal masks/defaults */ + /* + * Set signal masks/defaults. + * Use unwrapped syscall, libthr is in undefined state after vfork(). + */ if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) { - _sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); + __libc_sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); } if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) { for (i = 1; i <= _SIG_MAXSIG; i++) { if (sigismember(&sa->sa_sigdefault, i)) - if (_sigaction(i, &sigact, NULL) != 0) + if (__libc_sigaction(i, &sigact, NULL) != 0) return (errno); } } diff --git a/lib/libc/gen/readpassphrase.c b/lib/libc/gen/readpassphrase.c index 95ae725..60051a1 100644 --- a/lib/libc/gen/readpassphrase.c +++ b/lib/libc/gen/readpassphrase.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include <readpassphrase.h> #include "un-namespace.h" +#include "libc_private.h" static volatile sig_atomic_t signo[NSIG]; @@ -104,15 +105,15 @@ restart: sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* don't restart system calls */ sa.sa_handler = handler; - (void)_sigaction(SIGALRM, &sa, &savealrm); - (void)_sigaction(SIGHUP, &sa, &savehup); - (void)_sigaction(SIGINT, &sa, &saveint); - (void)_sigaction(SIGPIPE, &sa, &savepipe); - (void)_sigaction(SIGQUIT, &sa, &savequit); - (void)_sigaction(SIGTERM, &sa, &saveterm); - (void)_sigaction(SIGTSTP, &sa, &savetstp); - (void)_sigaction(SIGTTIN, &sa, &savettin); - (void)_sigaction(SIGTTOU, &sa, &savettou); + (void)__libc_sigaction(SIGALRM, &sa, &savealrm); + (void)__libc_sigaction(SIGHUP, &sa, &savehup); + (void)__libc_sigaction(SIGINT, &sa, &saveint); + (void)__libc_sigaction(SIGPIPE, &sa, &savepipe); + (void)__libc_sigaction(SIGQUIT, &sa, &savequit); + (void)__libc_sigaction(SIGTERM, &sa, &saveterm); + (void)__libc_sigaction(SIGTSTP, &sa, &savetstp); + (void)__libc_sigaction(SIGTTIN, &sa, &savettin); + (void)__libc_sigaction(SIGTTOU, &sa, &savettou); if (!(flags & RPP_STDIN)) (void)_write(output, prompt, strlen(prompt)); @@ -142,15 +143,15 @@ restart: errno == EINTR && !signo[SIGTTOU]) continue; } - (void)_sigaction(SIGALRM, &savealrm, NULL); - (void)_sigaction(SIGHUP, &savehup, NULL); - (void)_sigaction(SIGINT, &saveint, NULL); - (void)_sigaction(SIGQUIT, &savequit, NULL); - (void)_sigaction(SIGPIPE, &savepipe, NULL); - (void)_sigaction(SIGTERM, &saveterm, NULL); - (void)_sigaction(SIGTSTP, &savetstp, NULL); - (void)_sigaction(SIGTTIN, &savettin, NULL); - (void)_sigaction(SIGTTOU, &savettou, NULL); + (void)__libc_sigaction(SIGALRM, &savealrm, NULL); + (void)__libc_sigaction(SIGHUP, &savehup, NULL); + (void)__libc_sigaction(SIGINT, &saveint, NULL); + (void)__libc_sigaction(SIGQUIT, &savequit, NULL); + (void)__libc_sigaction(SIGPIPE, &savepipe, NULL); + (void)__libc_sigaction(SIGTERM, &saveterm, NULL); + (void)__libc_sigaction(SIGTSTP, &savetstp, NULL); + (void)__libc_sigaction(SIGTTIN, &savettin, NULL); + (void)__libc_sigaction(SIGTTOU, &savettou, NULL); if (input != STDIN_FILENO) (void)_close(input); diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c index 815cf14..7525567 100644 --- a/lib/libc/gen/setmode.c +++ b/lib/libc/gen/setmode.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #endif #include "un-namespace.h" +#include "libc_private.h" #define SET_LEN 6 /* initial # of bitcmd struct to malloc */ #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ @@ -364,9 +365,9 @@ getumask(void) * handler, protect them as best we can. */ sigfillset(&sigset); - (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)__libc_sigprocmask(SIG_BLOCK, &sigset, &sigoset); (void)umask(mask = umask(0)); - (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &sigoset, NULL); return (mask); } diff --git a/lib/libc/gen/siginterrupt.c b/lib/libc/gen/siginterrupt.c index fde33ca..d99b772 100644 --- a/lib/libc/gen/siginterrupt.c +++ b/lib/libc/gen/siginterrupt.c @@ -43,14 +43,13 @@ __FBSDID("$FreeBSD$"); * after an instance of the indicated signal. */ int -siginterrupt(sig, flag) - int sig, flag; +siginterrupt(int sig, int flag) { extern sigset_t _sigintr __hidden; struct sigaction sa; int ret; - if ((ret = _sigaction(sig, (struct sigaction *)0, &sa)) < 0) + if ((ret = __libc_sigaction(sig, (struct sigaction *)0, &sa)) < 0) return (ret); if (flag) { sigaddset(&_sigintr, sig); @@ -59,5 +58,5 @@ siginterrupt(sig, flag) sigdelset(&_sigintr, sig); sa.sa_flags |= SA_RESTART; } - return (_sigaction(sig, &sa, (struct sigaction *)0)); + return (__libc_sigaction(sig, &sa, (struct sigaction *)0)); } diff --git a/lib/libc/gen/signal.c b/lib/libc/gen/signal.c index ee96dcc..70e7f17 100644 --- a/lib/libc/gen/signal.c +++ b/lib/libc/gen/signal.c @@ -44,9 +44,7 @@ __FBSDID("$FreeBSD$"); sigset_t _sigintr __hidden; /* shared with siginterrupt */ sig_t -signal(s, a) - int s; - sig_t a; +signal(int s, sig_t a) { struct sigaction sa, osa; @@ -55,7 +53,7 @@ signal(s, a) sa.sa_flags = 0; if (!sigismember(&_sigintr, s)) sa.sa_flags |= SA_RESTART; - if (_sigaction(s, &sa, &osa) < 0) + if (__libc_sigaction(s, &sa, &osa) < 0) return (SIG_ERR); return (osa.sa_handler); } diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c index 958ddc6..859ca50 100644 --- a/lib/libc/gen/wordexp.c +++ b/lib/libc/gen/wordexp.c @@ -38,6 +38,7 @@ #include <unistd.h> #include <wordexp.h> #include "un-namespace.h" +#include "libc_private.h" __FBSDID("$FreeBSD$"); @@ -127,12 +128,12 @@ we_askshell(const char *words, wordexp_t *we, int flags) return (WRDE_NOSPACE); /* XXX */ (void)sigemptyset(&newsigblock); (void)sigaddset(&newsigblock, SIGCHLD); - (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); + (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); if ((pid = fork()) < 0) { serrno = errno; _close(pdes[0]); _close(pdes[1]); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); errno = serrno; return (WRDE_NOSPACE); /* XXX */ } @@ -140,7 +141,7 @@ we_askshell(const char *words, wordexp_t *we, int flags) /* * We are the child; make /bin/sh expand `words'. */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); if ((pdes[1] != STDOUT_FILENO ? _dup2(pdes[1], STDOUT_FILENO) : _fcntl(pdes[1], F_SETFD, 0)) < 0) @@ -222,7 +223,7 @@ cleanup: do wpid = _waitpid(pid, &status, 0); while (wpid < 0 && errno == EINTR); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); if (error != 0) { errno = serrno; return (error); diff --git a/lib/libc/i386/gen/setjmp.S b/lib/libc/i386/gen/setjmp.S index 6e15868..eb33e10 100644 --- a/lib/libc/i386/gen/setjmp.S +++ b/lib/libc/i386/gen/setjmp.S @@ -50,21 +50,12 @@ __FBSDID("$FreeBSD$"); ENTRY(setjmp) movl 4(%esp),%ecx - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif leal 28(%ecx), %eax pushl %eax /* (sigset_t*)oset */ pushl $0 /* (sigset_t*)set */ pushl $1 /* SIG_BLOCK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%ecx movl 0(%esp),%edx movl %edx, 0(%ecx) @@ -81,21 +72,12 @@ END(setjmp) WEAK_REFERENCE(__longjmp, longjmp) ENTRY(__longjmp) movl 4(%esp),%edx - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif pushl $0 /* (sigset_t*)oset */ leal 28(%edx), %eax pushl %eax /* (sigset_t*)set */ pushl $3 /* SIG_SETMASK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%edx movl 8(%esp),%eax movl 0(%edx),%ecx diff --git a/lib/libc/i386/gen/sigsetjmp.S b/lib/libc/i386/gen/sigsetjmp.S index 1c63649..7566d72 100644 --- a/lib/libc/i386/gen/sigsetjmp.S +++ b/lib/libc/i386/gen/sigsetjmp.S @@ -59,21 +59,12 @@ ENTRY(sigsetjmp) movl %eax,44(%ecx) testl %eax,%eax jz 2f - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif leal 28(%ecx), %eax pushl %eax /* (sigset_t*)oset */ pushl $0 /* (sigset_t*)set */ pushl $1 /* SIG_BLOCK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%ecx 2: movl 0(%esp),%edx movl %edx, 0(%ecx) @@ -92,21 +83,12 @@ ENTRY(__siglongjmp) movl 4(%esp),%edx cmpl $0,44(%edx) jz 2f - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif pushl $0 /* (sigset_t*)oset */ leal 28(%edx), %eax pushl %eax /* (sigset_t*)set */ pushl $3 /* SIG_SETMASK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%edx 2: movl 8(%esp),%eax movl 0(%edx),%ecx diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index a670d63..5caf9a3 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -359,6 +359,11 @@ __pid_t __sys_wait6(enum idtype, __id_t, int *, int, __ssize_t __sys_write(int, const void *, __size_t); __ssize_t __sys_writev(int, const struct iovec *, int); +int __libc_sigaction(int, const struct sigaction *, + struct sigaction *) __hidden; +int __libc_sigprocmask(int, const __sigset_t *, __sigset_t *) + __hidden; +int __libc_sigsuspend(const __sigset_t *) __hidden; int __libc_sigwait(const __sigset_t * __restrict, int * restrict sig); int __libc_system(const char *); diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c index 2885dc3..1ba9888 100644 --- a/lib/libc/net/rcmd.c +++ b/lib/libc/net/rcmd.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #endif #include <arpa/nameser.h> #include "un-namespace.h" +#include "libc_private.h" extern int innetgr( const char *, const char *, const char *, const char * ); @@ -148,7 +149,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) refused = 0; sigemptyset(&newmask); sigaddset(&newmask, SIGURG); - _sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); + __libc_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); for (timo = 1, lport = IPPORT_RESERVED - 1;;) { s = rresvport_af(&lport, ai->ai_family); if (s < 0) { @@ -163,7 +164,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) (void)fprintf(stderr, "rcmd: socket: %s\n", strerror(errno)); freeaddrinfo(res); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } @@ -181,7 +182,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) (void)fprintf(stderr, "%s: %s\n", *ahost, strerror(errno)); freeaddrinfo(res); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } @@ -306,7 +307,7 @@ again: } goto bad2; } - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (s); bad2: @@ -314,7 +315,7 @@ bad2: (void)_close(*fd2p); bad: (void)_close(s); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (-1); } diff --git a/lib/libc/stdio/tmpfile.c b/lib/libc/stdio/tmpfile.c index c67d1e4..e5a2be1 100644 --- a/lib/libc/stdio/tmpfile.c +++ b/lib/libc/stdio/tmpfile.c @@ -46,9 +46,10 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <paths.h> #include "un-namespace.h" +#include "libc_private.h" FILE * -tmpfile() +tmpfile(void) { sigset_t set, oset; FILE *fp; @@ -69,7 +70,7 @@ tmpfile() return (NULL); sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); fd = mkstemp(buf); if (fd != -1) @@ -77,7 +78,7 @@ tmpfile() free(buf); - (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, NULL); if (fd == -1) return (NULL); diff --git a/lib/libc/stdlib/abort.c b/lib/libc/stdlib/abort.c index b137e49..022c6aa 100644 --- a/lib/libc/stdlib/abort.c +++ b/lib/libc/stdlib/abort.c @@ -61,7 +61,7 @@ abort() * any errors -- ISO C doesn't allow abort to return anyway. */ sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); (void)raise(SIGABRT); /* @@ -71,9 +71,9 @@ abort() act.sa_handler = SIG_DFL; act.sa_flags = 0; sigfillset(&act.sa_mask); - (void)_sigaction(SIGABRT, &act, NULL); + (void)__libc_sigaction(SIGABRT, &act, NULL); sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); (void)raise(SIGABRT); exit(1); } diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c index bd9ea5a..2b298e4 100644 --- a/lib/libc/stdlib/system.c +++ b/lib/libc/stdlib/system.c @@ -70,16 +70,20 @@ __libc_system(const char *command) (void)sigaddset(&newsigblock, SIGCHLD); (void)sigaddset(&newsigblock, SIGINT); (void)sigaddset(&newsigblock, SIGQUIT); - (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); + (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); switch(pid = vfork()) { + /* + * In the child, use unwrapped syscalls. libthr is in + * undefined state after vfork(). + */ case -1: /* error */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); return (-1); case 0: /* child */ /* * Restore original signal dispositions and exec the command. */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__sys_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); _exit(127); } @@ -92,16 +96,16 @@ __libc_system(const char *command) memset(&ign, 0, sizeof(ign)); ign.sa_handler = SIG_IGN; (void)sigemptyset(&ign.sa_mask); - (void)_sigaction(SIGINT, &ign, &intact); - (void)_sigaction(SIGQUIT, &ign, &quitact); + (void)__libc_sigaction(SIGINT, &ign, &intact); + (void)__libc_sigaction(SIGQUIT, &ign, &quitact); savedpid = pid; do { pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); - (void)_sigaction(SIGINT, &intact, NULL); - (void)_sigaction(SIGQUIT, &quitact, NULL); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - return(pid == -1 ? -1 : pstat); + (void)__libc_sigaction(SIGINT, &intact, NULL); + (void)__libc_sigaction(SIGQUIT, &quitact, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + return (pid == -1 ? -1 : pstat); } __weak_reference(__libc_system, __system); diff --git a/lib/libc/sys/sigaction.c b/lib/libc/sys/sigaction.c index 7645538..b4d6563 100644 --- a/lib/libc/sys/sigaction.c +++ b/lib/libc/sys/sigaction.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" __weak_reference(__sys_sigaction, __sigaction); +__weak_reference(sigaction, __libc_sigaction); #pragma weak sigaction int diff --git a/lib/libc/sys/sigprocmask.c b/lib/libc/sys/sigprocmask.c index 40dba95..d24bb89 100644 --- a/lib/libc/sys/sigprocmask.c +++ b/lib/libc/sys/sigprocmask.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" __weak_reference(__sys_sigprocmask, __sigprocmask); +__weak_reference(sigprocmask, __libc_sigprocmask); #pragma weak sigprocmask int diff --git a/lib/libc/sys/sigsuspend.c b/lib/libc/sys/sigsuspend.c index 6e47368..1f980a1 100644 --- a/lib/libc/sys/sigsuspend.c +++ b/lib/libc/sys/sigsuspend.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" __weak_reference(__sys_sigsuspend, __sigsuspend); +__weak_reference(sigsuspend, __libc_sigsuspend); #pragma weak sigsuspend int
On 08/29/2015 15:41, Konstantin Belousov wrote:> On Sat, Aug 29, 2015 at 03:01:38PM +0200, Jilles Tjoelker wrote: >> Looks good to me, except that I think a vforked child (in system() and >> posix_spawn*()) should use the system calls and not libthr's wrappers. >> This reduces the probability of weird things happening between vfork and >> exec, and also avoids an unexpected error when >> posix_spawnattr_setsigdefault()'s mask contains SIGTHR. > > Thank you for the review, I agree with the note about vfork. Updated > patch is below. Also, I removed the PIC_PROLOGUE from the i386 setjmp, > it has no use after the plt calls are removed.I verified the patch. The getumask part of lib/libc/gen/setmode.c part was rejected on stable/10 (probably due to other changes in ^/head.) Cheers Michiel
On Sat, Aug 29, 2015 at 04:41:30PM +0300, Konstantin Belousov wrote:> On Sat, Aug 29, 2015 at 03:01:38PM +0200, Jilles Tjoelker wrote: > > Looks good to me, except that I think a vforked child (in system() and > > posix_spawn*()) should use the system calls and not libthr's wrappers. > > This reduces the probability of weird things happening between vfork and > > exec, and also avoids an unexpected error when > > posix_spawnattr_setsigdefault()'s mask contains SIGTHR.> Thank you for the review, I agree with the note about vfork. Updated > patch is below. Also, I removed the PIC_PROLOGUE from the i386 setjmp, > it has no use after the plt calls are removed.> [snip] > diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c > index e3124b2..673c760 100644 > --- a/lib/libc/gen/posix_spawn.c > +++ b/lib/libc/gen/posix_spawn.c > @@ -118,15 +118,18 @@ process_spawnattr(const posix_spawnattr_t sa) > return (errno); > } > > - /* Set signal masks/defaults */ > + /* > + * Set signal masks/defaults. > + * Use unwrapped syscall, libthr is in undefined state after vfork(). > + */ > if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) { > - _sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); > + __libc_sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); > } > > if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) { > for (i = 1; i <= _SIG_MAXSIG; i++) { > if (sigismember(&sa->sa_sigdefault, i)) > - if (_sigaction(i, &sigact, NULL) != 0) > + if (__libc_sigaction(i, &sigact, NULL) != 0) > return (errno); > } > }Hmm, the comments say direct syscalls are being used, but in fact libthr's interposer is called. The change to system() does correctly use __sys_sigprocmask(). -- Jilles Tjoelker