From a5133d1a797dd8035aac6e5c921736a9ee085a4d Mon Sep 17 00:00:00 2001 From: delphij Date: Wed, 16 Sep 2015 20:59:41 +0000 Subject: [PATCH] Fix regression in pw(8) when creating numeric users or groups. [EN-15:16] Fix libc handling of signals for multi-threaded processes. [EN-15:17] Implement pubkey support for pkg(7) bootstrap. [EN-15:18] Approved by: so git-svn-id: https://svn.freebsd.org/base/releng/10.2@287872 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- UPDATING | 12 ++ lib/libc/amd64/gen/setjmp.S | 4 +- lib/libc/amd64/gen/sigsetjmp.S | 4 +- lib/libc/compat-43/sigcompat.c | 28 ++--- lib/libc/db/btree/bt_open.c | 5 +- lib/libc/db/hash/hash_page.c | 5 +- lib/libc/gen/daemon.c | 8 +- lib/libc/gen/posix_spawn.c | 9 +- lib/libc/gen/readpassphrase.c | 37 +++--- lib/libc/gen/setmode.c | 5 +- lib/libc/gen/siginterrupt.c | 7 +- lib/libc/gen/signal.c | 6 +- lib/libc/gen/wordexp.c | 9 +- lib/libc/i386/gen/setjmp.S | 22 +--- lib/libc/i386/gen/sigsetjmp.S | 22 +--- lib/libc/include/libc_private.h | 5 + lib/libc/net/rcmd.c | 11 +- lib/libc/stdio/tmpfile.c | 7 +- lib/libc/stdlib/abort.c | 6 +- lib/libc/stdlib/system.c | 22 ++-- lib/libc/sys/sigaction.c | 1 + lib/libc/sys/sigprocmask.c | 1 + lib/libc/sys/sigsuspend.c | 1 + sys/conf/newvers.sh | 2 +- usr.sbin/pkg/config.c | 11 ++ usr.sbin/pkg/config.h | 1 + usr.sbin/pkg/pkg.c | 197 +++++++++++++++++++++++++++----- usr.sbin/pw/pw.c | 9 +- 28 files changed, 296 insertions(+), 161 deletions(-) diff --git a/UPDATING b/UPDATING index 3ce3a1156..c877003cc 100644 --- a/UPDATING +++ b/UPDATING @@ -16,6 +16,18 @@ from older versions of FreeBSD, try WITHOUT_CLANG to bootstrap to the tip of stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20150916: p3 FreeBSD-EN-15:16.pw + FreeBSD-EN-15:17.libc + FreeBSD-EN-15:18.pkg + + Fix regression in pw(8) when creating numeric users or groups. + [EN-15:16] + + Fix libc handling of signals for multi-threaded processes. + [EN-15:17] + + Implement pubkey support for pkg(7) bootstrap. [EN-15:18] + 20150825: p2 FreeBSD-SA-15:22.openssh FreeBSD-EN-15:15.pkg Fix OpenSSH multiple vulnerabilities. [SA-15:22] diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S index 47772be88..4ec4d79eb 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 */ @@ -83,7 +83,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 ef90bc6aa..431255901 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 */ @@ -92,7 +92,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 199846fd2..a8cef1c14 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 94ba014ed..051fc28e9 100644 --- a/lib/libc/db/btree/bt_open.c +++ b/lib/libc/db/btree/bt_open.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include #include #include "un-namespace.h" +#include "libc_private.h" #include #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 d319d988c..8040419f7 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #endif #include "un-namespace.h" +#include "libc_private.h" #include #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 b359a87aa..15c6f4af7 100644 --- a/lib/libc/gen/daemon.c +++ b/lib/libc/gen/daemon.c @@ -41,10 +41,10 @@ __FBSDID("$FreeBSD$"); #include #include #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 e3124b2e2..c65a73087 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); + __sys_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 (__sys_sigaction(i, &sigact, NULL) != 0) return (errno); } } diff --git a/lib/libc/gen/readpassphrase.c b/lib/libc/gen/readpassphrase.c index 95ae725e0..60051a189 100644 --- a/lib/libc/gen/readpassphrase.c +++ b/lib/libc/gen/readpassphrase.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #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 9dc5d9fb5..4c05ee0e7 100644 --- a/lib/libc/gen/setmode.c +++ b/lib/libc/gen/setmode.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #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 */ @@ -187,10 +188,10 @@ setmode(const char *p) * as best we can. */ sigfillset(&sigset); - (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)__libc_sigprocmask(SIG_BLOCK, &sigset, &sigoset); (void)umask(mask = umask(0)); mask = ~mask; - (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &sigoset, NULL); setlen = SET_LEN + 2; diff --git a/lib/libc/gen/siginterrupt.c b/lib/libc/gen/siginterrupt.c index fde33ca56..d99b77233 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 ee96dcc3c..70e7f1712 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 c7f4b1d0e..329044d32 100644 --- a/lib/libc/gen/wordexp.c +++ b/lib/libc/gen/wordexp.c @@ -38,6 +38,7 @@ #include #include #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 */ } @@ -141,7 +142,7 @@ we_askshell(const char *words, wordexp_t *we, int flags) * We are the child; just get /bin/sh to run the wordexp * builtin on `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) @@ -210,7 +211,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 a409e35e7..a7b424e6e 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) @@ -82,21 +73,12 @@ END(setjmp) .set CNAME(longjmp),CNAME(__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 936edbae3..9c29d9ed5 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) @@ -93,21 +84,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 62c547a39..b43e8d15e 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -368,6 +368,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 2885dc331..1ba98888e 100644 --- a/lib/libc/net/rcmd.c +++ b/lib/libc/net/rcmd.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #endif #include #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 c67d1e456..e5a2be1d9 100644 --- a/lib/libc/stdio/tmpfile.c +++ b/lib/libc/stdio/tmpfile.c @@ -46,9 +46,10 @@ __FBSDID("$FreeBSD$"); #include #include #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 b137e490e..022c6aa99 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 bd9ea5a30..2b298e45a 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 7645538cf..b4d65639b 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 40dba9556..d24bb89c1 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 6e47368c4..1f980a117 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 diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 45ca709b2..2c29cee14 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="10.2" -BRANCH="RELEASE-p2" +BRANCH="RELEASE-p3" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c index 3a1f18d25..b0271f580 100644 --- a/usr.sbin/pkg/config.c +++ b/usr.sbin/pkg/config.c @@ -131,6 +131,15 @@ static struct config_entry c[] = { false, true, }, + [PUBKEY] = { + PKG_CONFIG_STRING, + "PUBKEY", + NULL, + NULL, + NULL, + false, + false + } }; static int @@ -231,6 +240,8 @@ config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype) sbuf_cpy(buf, "SIGNATURE_TYPE"); else if (strcasecmp(key, "fingerprints") == 0) sbuf_cpy(buf, "FINGERPRINTS"); + else if (strcasecmp(key, "pubkey") == 0) + sbuf_cpy(buf, "PUBKEY"); else if (strcasecmp(key, "enabled") == 0) { if ((cur->type != UCL_BOOLEAN) || !ucl_object_toboolean(cur)) diff --git a/usr.sbin/pkg/config.h b/usr.sbin/pkg/config.h index ea0d0005d..4ff0a1673 100644 --- a/usr.sbin/pkg/config.h +++ b/usr.sbin/pkg/config.h @@ -40,6 +40,7 @@ typedef enum { SIGNATURE_TYPE, FINGERPRINTS, REPOS_DIR, + PUBKEY, CONFIG_SIZE } pkg_config_key; diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c index e242638e0..fc2192dc0 100644 --- a/usr.sbin/pkg/pkg.c +++ b/usr.sbin/pkg/pkg.c @@ -65,6 +65,11 @@ struct sig_cert { bool trusted; }; +struct pubkey { + unsigned char *sig; + int siglen; +}; + typedef enum { HASH_UNKNOWN, HASH_SHA256, @@ -469,6 +474,25 @@ cleanup: return (ret); } +static EVP_PKEY * +load_public_key_file(const char *file) +{ + EVP_PKEY *pkey; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_file(file, "r"); + if (!bp) + errx(EXIT_FAILURE, "Unable to read %s", file); + + if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) + warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf)); + + BIO_free(bp); + + return (pkey); +} + static EVP_PKEY * load_public_key_buf(const unsigned char *cert, int certlen) { @@ -487,8 +511,8 @@ load_public_key_buf(const unsigned char *cert, int certlen) } static bool -rsa_verify_cert(int fd, const unsigned char *key, int keylen, - unsigned char *sig, int siglen) +rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key, + int keylen, unsigned char *sig, int siglen) { EVP_MD_CTX *mdctx; EVP_PKEY *pkey; @@ -500,6 +524,8 @@ rsa_verify_cert(int fd, const unsigned char *key, int keylen, mdctx = NULL; ret = false; + SSL_load_error_strings(); + /* Compute SHA256 of the package. */ if (lseek(fd, 0, 0) == -1) { warn("lseek"); @@ -510,9 +536,16 @@ rsa_verify_cert(int fd, const unsigned char *key, int keylen, goto cleanup; } - if ((pkey = load_public_key_buf(key, keylen)) == NULL) { - warnx("Error reading public key"); - goto cleanup; + if (sigfile != NULL) { + if ((pkey = load_public_key_file(sigfile)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } + } else { + if ((pkey = load_public_key_buf(key, keylen)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } } /* Verify signature of the SHA256(pkg) is valid. */ @@ -552,6 +585,35 @@ cleanup: return (ret); } +static struct pubkey * +read_pubkey(int fd) +{ + struct pubkey *pk; + struct sbuf *sig; + char buf[4096]; + int r; + + if (lseek(fd, 0, 0) == -1) { + warn("lseek"); + return (NULL); + } + + sig = sbuf_new_auto(); + + while ((r = read(fd, buf, sizeof(buf))) >0) { + sbuf_bcat(sig, buf, r); + } + + sbuf_finish(sig); + pk = calloc(1, sizeof(struct pubkey)); + pk->siglen = sbuf_len(sig); + pk->sig = calloc(1, pk->siglen); + memcpy(pk->sig, sbuf_data(sig), pk->siglen); + sbuf_delete(sig); + + return (pk); +} + static struct sig_cert * parse_cert(int fd) { int my_fd; @@ -624,6 +686,45 @@ parse_cert(int fd) { return (sc); } +static bool +verify_pubsignature(int fd_pkg, int fd_sig) +{ + struct pubkey *pk; + const char *pubkey; + bool ret; + + pk = NULL; + pubkey = NULL; + ret = false; + if (config_string(PUBKEY, &pubkey) != 0) { + warnx("No CONFIG_PUBKEY defined"); + goto cleanup; + } + + if ((pk = read_pubkey(fd_sig)) == NULL) { + warnx("Error reading signature"); + goto cleanup; + } + + /* Verify the signature. */ + printf("Verifying signature with public key %s... ", pubkey); + if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig, + pk->siglen) == false) { + fprintf(stderr, "Signature is not valid\n"); + goto cleanup; + } + + ret = true; + +cleanup: + if (pk) { + free(pk->sig); + free(pk); + } + + return (ret); +} + static bool verify_signature(int fd_pkg, int fd_sig) { @@ -702,7 +803,7 @@ verify_signature(int fd_pkg, int fd_sig) /* Verify the signature. */ printf("Verifying signature with trusted certificate %s... ", sc->name); - if (rsa_verify_cert(fd_pkg, sc->cert, sc->certlen, sc->sig, + if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig, sc->siglen) == false) { fprintf(stderr, "Signature is not valid\n"); goto cleanup; @@ -768,24 +869,42 @@ bootstrap_pkg(bool force) if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { - snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", - getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); - snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", - packagesite); + snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", + packagesite); - if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto fetchfail; - } + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } + + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { - if (verify_signature(fd_pkg, fd_sig) == false) + snprintf(tmpsig, MAXPATHLEN, + "%s/pkg.txz.pubkeysig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.pubkeysig", + packagesite); + + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } + + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) @@ -862,21 +981,37 @@ bootstrap_pkg_local(const char *pkgpath, bool force) } if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { - snprintf(path, sizeof(path), "%s.sig", pkgpath); + snprintf(path, sizeof(path), "%s.sig", pkgpath); - if ((fd_sig = open(path, O_RDONLY)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto cleanup; - } + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } - if (verify_signature(fd_pkg, fd_sig) == false) + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { + + snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath); + + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } + + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index f4704a4fb..6eb93fcf9 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -272,14 +272,7 @@ main(int argc, char *argv[]) errstr); break; case 'n': - if (strspn(optarg, "0123456789") != strlen(optarg)) { - name = optarg; - break; - } - id = strtonum(optarg, 0, LONG_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad id '%s': %s", optarg, - errstr); + name = optarg; break; case 'o': conf.checkduplicate = false; -- 2.42.0