From owner-svn-src-head@freebsd.org Mon Aug 20 02:17:56 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 A5F89108015C; Mon, 20 Aug 2018 02:17:56 +0000 (UTC) (envelope-from delphij@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 4CD40757B9; Mon, 20 Aug 2018 02:17:56 +0000 (UTC) (envelope-from delphij@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 29BF170CC; Mon, 20 Aug 2018 02:17:56 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w7K2Huha021339; Mon, 20 Aug 2018 02:17:56 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w7K2Huem021338; Mon, 20 Aug 2018 02:17:56 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201808200217.w7K2Huem021338@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Mon, 20 Aug 2018 02:17:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r338084 - head/lib/libc/gen X-SVN-Group: head X-SVN-Commit-Author: delphij X-SVN-Commit-Paths: head/lib/libc/gen X-SVN-Commit-Revision: 338084 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.27 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: Mon, 20 Aug 2018 02:17:57 -0000 Author: delphij Date: Mon Aug 20 02:17:55 2018 New Revision: 338084 URL: https://svnweb.freebsd.org/changeset/base/338084 Log: In r331279 the code used ENOSYS to check the existence of getrandom(2). This will only work if the caller already handles SIGSYS, which is not always the case. Address this by checking osreldate instead. Note that because there was not __FreeBSD_version bump when the system call was added, use 1200061 (r332100) which is the first bump after the introduction of the system call. PR: 230762 Reported by: Jenkins via Mark Millard Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D16807 Modified: head/lib/libc/gen/getentropy.c Modified: head/lib/libc/gen/getentropy.c ============================================================================== --- head/lib/libc/gen/getentropy.c Mon Aug 20 02:08:39 2018 (r338083) +++ head/lib/libc/gen/getentropy.c Mon Aug 20 02:17:55 2018 (r338084) @@ -34,10 +34,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include "libc_private.h" +/* First __FreeBSD_version bump after introduction of getrandom(2) (r331279) */ +#define GETRANDOM_FIRST 1200061 + extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); static size_t @@ -99,21 +103,38 @@ int getentropy(void *buf, size_t buflen) { ssize_t rd; + bool have_getrandom; if (buflen > 256) { errno = EIO; return (-1); } + have_getrandom = (__getosreldate() >= GETRANDOM_FIRST); + while (buflen > 0) { - rd = getrandom(buf, buflen, 0); - if (rd == -1) { - if (errno == EINTR) - continue; - else if (errno == ENOSYS || errno == ECAPMODE) - return (getentropy_fallback(buf, buflen)); - else - return (-1); + if (have_getrandom) { + rd = getrandom(buf, buflen, 0); + if (rd == -1) { + switch (errno) { + case ECAPMODE: + /* + * Kernel >= r331280 and < r337999 + * will return ECAPMODE when the + * caller is already in capability + * mode, fallback to traditional + * method in this case. + */ + have_getrandom = false; + continue; + case EINTR: + continue; + default: + return (-1); + } + } + } else { + return (getentropy_fallback(buf, buflen)); } /* This cannot happen. */