mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 04:22:44 +00:00
getentropy: Remove fallback code
Some checks are pending
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, arm64, aarch64) (push) Waiting to run
Some checks are pending
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, arm64, aarch64) (push) Waiting to run
We don't in general support running newer libc on an older kernel, but have occasionally added support for specific functionality on a case-by- case basis. When we do this it is usually done as an aid for developers to get across a change that introduced new functionality, as for 64-bit inodes and the introduction of the getrandom syscall. The getrandom syscall was added in commite9ac27430c
("Implement getrandom(2) and getentropy(3)") in 2018, and exists in all supported FreeBSD versions. The ECAPMODE special case applied to a few months worth of kernel versions also in 2018 -- fixed as of commited1fa01ac4
("Regen after r337998."). The backwards-compatibility support is no longer needed, so remove it. Relnotes: Yes Reviewed by: brooks, cem, delphij Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D47636
This commit is contained in:
parent
3c29734502
commit
62dab3d016
@ -28,121 +28,40 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ssp/ssp.h>
|
||||
|
||||
#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 inline void
|
||||
_getentropy_fail(void)
|
||||
{
|
||||
raise(SIGKILL);
|
||||
}
|
||||
|
||||
static size_t
|
||||
arnd_sysctl(u_char *buf, size_t size)
|
||||
{
|
||||
int mib[2];
|
||||
size_t len, done;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_ARND;
|
||||
done = 0;
|
||||
|
||||
do {
|
||||
len = size;
|
||||
if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
|
||||
return (done);
|
||||
done += len;
|
||||
buf += len;
|
||||
size -= len;
|
||||
} while (size > 0);
|
||||
|
||||
return (done);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (arnd_sysctl(buf, buflen) != buflen) {
|
||||
if (errno == EFAULT)
|
||||
return (-1);
|
||||
/*
|
||||
* This cannot happen. arnd_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, excepting the user-provided-a-bogus-
|
||||
* buffer EFAULT, give up (like for arc4random(3)'s arc4_stir).
|
||||
*/
|
||||
_getentropy_fail();
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
__ssp_real(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) {
|
||||
if (have_getrandom) {
|
||||
rd = getrandom(buf, buflen, 0);
|
||||
if (rd == -1) {
|
||||
switch (errno) {
|
||||
case ECAPMODE:
|
||||
/*
|
||||
* Kernel >= r331280 (4948f7bf1153)
|
||||
* and < r337999 (ed1fa01ac45a) 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;
|
||||
case EFAULT:
|
||||
return (-1);
|
||||
default:
|
||||
_getentropy_fail();
|
||||
}
|
||||
rd = getrandom(buf, buflen, 0);
|
||||
if (rd == -1) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
continue;
|
||||
case EFAULT:
|
||||
return (-1);
|
||||
default:
|
||||
_getentropy_fail();
|
||||
}
|
||||
} else {
|
||||
return (getentropy_fallback(buf, buflen));
|
||||
}
|
||||
|
||||
/* This cannot happen. */
|
||||
|
Loading…
Reference in New Issue
Block a user