Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167582356
D14785.id40568.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D14785.id40568.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D14785: getentropy(3): Fallback to kern.arandom sysctl on older kernels
Attached
Detach File
Event Timeline
Log In to Comment