From owner-svn-src-head@freebsd.org Wed Mar 21 23:52:38 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 33525F4F8C5; Wed, 21 Mar 2018 23:52:38 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id DA9C76FEFB; Wed, 21 Mar 2018 23:52:37 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D5690166D; Wed, 21 Mar 2018 23:52:37 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w2LNqbAs075737; Wed, 21 Mar 2018 23:52:37 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w2LNqbH4075731; Wed, 21 Mar 2018 23:52:37 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201803212352.w2LNqbH4075731@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Wed, 21 Mar 2018 23:52:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331334 - in head/lib/libc: gen include sys tests/gen X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head/lib/libc: gen include sys tests/gen X-SVN-Commit-Revision: 331334 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Mar 2018 23:52:38 -0000 Author: cem Date: Wed Mar 21 23:52:37 2018 New Revision: 331334 URL: https://svnweb.freebsd.org/changeset/base/331334 Log: getentropy(3): Fallback to kern.arandom sysctl on older kernels On older kernels, when userspace program disables SIGSYS, catch ENOSYS and emulate getrandom(2) syscall with the kern.arandom sysctl (via existing arc4_sysctl wrapper). Special care is taken to faithfully emulate EFAULT on NULL pointers, because sysctl(3) as used by kern.arandom ignores NULL oldp. (This was caught by getentropy(3) ATF tests.) Reported by: kib Reviewed by: kib Discussed with: delphij Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D14785 Modified: head/lib/libc/gen/arc4random.c head/lib/libc/gen/getentropy.c head/lib/libc/include/libc_private.h head/lib/libc/sys/Symbol.map head/lib/libc/tests/gen/getentropy_test.c Modified: head/lib/libc/gen/arc4random.c ============================================================================== --- head/lib/libc/gen/arc4random.c Wed Mar 21 23:51:14 2018 (r331333) +++ head/lib/libc/gen/arc4random.c Wed Mar 21 23:52:37 2018 (r331334) @@ -111,8 +111,8 @@ arc4_addrandom(u_char *dat, int datlen) rs.j = rs.i; } -static size_t -arc4_sysctl(u_char *buf, size_t size) +size_t +__arc4_sysctl(u_char *buf, size_t size) { int mib[2]; size_t len, done; @@ -143,7 +143,7 @@ arc4_stir(void) arc4_init(); rs_initialized = 1; } - if (arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) { + if (__arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) { /* * The sysctl cannot fail. If it does fail on some FreeBSD * derivative or after some future change, just abort so that Modified: head/lib/libc/gen/getentropy.c ============================================================================== --- head/lib/libc/gen/getentropy.c Wed Mar 21 23:51:14 2018 (r331333) +++ head/lib/libc/gen/getentropy.c Wed Mar 21 23:52:37 2018 (r331334) @@ -37,6 +37,39 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" +/* + * If a newer libc is accidentally installed on an older kernel, provide high + * quality random data anyway. The sysctl interface is not as fast and does + * not block by itself, but is provided by even very old kernels. + */ +static int +getentropy_fallback(void *buf, size_t buflen) +{ + /* + * oldp (buf) == NULL has a special meaning for sysctl that results in + * no EFAULT. For compatibility with the kernel getrandom(2), detect + * this case and return the appropriate error. + */ + if (buf == NULL && buflen > 0) { + errno = EFAULT; + return (-1); + } + if (__arc4_sysctl(buf, buflen) != buflen) { + if (errno == EFAULT) + return (-1); + /* + * This cannot happen. _arc4_sysctl() spins until the random + * device is seeded and then repeatedly reads until the full + * request is satisfied. The only way for this to return a zero + * byte or short read is if sysctl(2) on the kern.arandom MIB + * fails. In this case, exceping the user-provided-a-bogus- + * buffer EFAULT, give up (like for arc4random(3)'s arc4_stir). + */ + abort(); + } + return (0); +} + int getentropy(void *buf, size_t buflen) { @@ -53,7 +86,7 @@ getentropy(void *buf, size_t buflen) if (errno == EINTR) continue; else if (errno == ENOSYS) - abort(); + return (getentropy_fallback(buf, buflen)); else return (-1); } Modified: head/lib/libc/include/libc_private.h ============================================================================== --- head/lib/libc/include/libc_private.h Wed Mar 21 23:51:14 2018 (r331333) +++ head/lib/libc/include/libc_private.h Wed Mar 21 23:52:37 2018 (r331334) @@ -405,6 +405,8 @@ int __sys_futimens(int fd, const struct timespec *tim int __sys_utimensat(int fd, const char *path, const struct timespec *times, int flag) __hidden; +__size_t __arc4_sysctl(unsigned char *, __size_t); + /* execve() with PATH processing to implement posix_spawnp() */ int _execvpe(const char *, char * const *, char * const *); Modified: head/lib/libc/sys/Symbol.map ============================================================================== --- head/lib/libc/sys/Symbol.map Wed Mar 21 23:51:14 2018 (r331333) +++ head/lib/libc/sys/Symbol.map Wed Mar 21 23:52:37 2018 (r331334) @@ -628,8 +628,6 @@ FBSDprivate_1.0 { __sys_getppid; _getpriority; __sys_getpriority; - _getrandom; - __sys_getrandom; _getresgid; __sys_getresgid; _getresuid; Modified: head/lib/libc/tests/gen/getentropy_test.c ============================================================================== --- head/lib/libc/tests/gen/getentropy_test.c Wed Mar 21 23:51:14 2018 (r331333) +++ head/lib/libc/tests/gen/getentropy_test.c Wed Mar 21 23:52:37 2018 (r331334) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -76,6 +77,8 @@ ATF_TC_BODY(getentropy_sizes, tc) ATF_TP_ADD_TCS(tp) { + + signal(SIGSYS, SIG_IGN); ATF_TP_ADD_TC(tp, getentropy_count); ATF_TP_ADD_TC(tp, getentropy_fault);