Page MenuHomeFreeBSD

D14785.id40568.diff
No OneTemporary

D14785.id40568.diff

Index: lib/libc/gen/arc4random.c
===================================================================
--- lib/libc/gen/arc4random.c
+++ lib/libc/gen/arc4random.c
@@ -111,8 +111,8 @@
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_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
Index: lib/libc/gen/getentropy.c
===================================================================
--- lib/libc/gen/getentropy.c
+++ lib/libc/gen/getentropy.c
@@ -37,6 +37,39 @@
#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 @@
if (errno == EINTR)
continue;
else if (errno == ENOSYS)
- abort();
+ return (getentropy_fallback(buf, buflen));
else
return (-1);
}
Index: lib/libc/include/libc_private.h
===================================================================
--- lib/libc/include/libc_private.h
+++ lib/libc/include/libc_private.h
@@ -405,6 +405,8 @@
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 *);
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -628,8 +628,6 @@
__sys_getppid;
_getpriority;
__sys_getpriority;
- _getrandom;
- __sys_getrandom;
_getresgid;
__sys_getresgid;
_getresuid;
Index: lib/libc/tests/gen/getentropy_test.c
===================================================================
--- lib/libc/tests/gen/getentropy_test.c
+++ lib/libc/tests/gen/getentropy_test.c
@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <errno.h>
+#include <signal.h>
#include <unistd.h>
#include <atf-c.h>
@@ -76,6 +77,8 @@
ATF_TP_ADD_TCS(tp)
{
+
+ signal(SIGSYS, SIG_IGN);
ATF_TP_ADD_TC(tp, getentropy_count);
ATF_TP_ADD_TC(tp, getentropy_fault);

File Metadata

Mime Type
text/plain
Expires
Sun, Aug 23, 9:06 PM (1 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37161255
Default Alt Text
D14785.id40568.diff (3 KB)

Event Timeline