Hi Lev, I took a first attempt at reproducing this problem on a fast desktop-class system. First steps, give us a way to revert back to unseeded status: --- a/sys/dev/random/fortuna.c +++ b/sys/dev/random/fortuna.c _at__at_ -39,6 +39,7 _at__at_ __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include <sys/param.h> +#include <sys/fail.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> _at__at_ -384,6 +385,17 _at__at_ random_fortuna_pre_read(void) return; } + /* + * When set, pretend we do not have enough entropy to reseed yet. + */ + KFAIL_POINT_CODE(DEBUG_FP, random_fortuna_pre_read, { + if (RETURN_VALUE != 0) { + RANDOM_RESEED_UNLOCK(); + return; + } + }); + + #ifdef _KERNEL fortuna_state.fs_lasttime = now; #endif _at__at_ -442,5 +454,11 _at__at_ bool random_fortuna_seeded(void) { + /* When set, act as if we are not seeded. */ + KFAIL_POINT_CODE(DEBUG_FP, random_fortuna_seeded, { + if (RETURN_VALUE != 0) + fortuna_state.fs_counter = UINT128_ZERO; + }); + return (!uint128_is_zero(fortuna_state.fs_counter)); } Second step, enable the failpoints and launch repro program: $ sudo sysctl debug.fail_point.random_fortuna_pre_read='return(1)' debug.fail_point.random_fortuna_pre_read: off -> return(1) $ sudo sysctl debug.fail_point.random_fortuna_seeded='return(1)' debug.fail_point.random_fortuna_seeded: off -> return(1) $ cat ./blocked_random_poc.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { printf("%x\n", arc4random()); return (0); } $ ./blocked_random_poc ... Third step, I looked at what that process was doing: Curiously, it is not in getrandom() at all, but instead the ARND sysctl fallback. I probably need to rebuild world (libc) to test this (new libc arc4random based on Chacha). $ procstat -kk 1196 PID TID COMM TDNAME KSTACK 1196 100435 blocked_random_poc - read_random+0x3d sysctl_kern_arnd+0x3a sysctl_root_handler_locked+0x89 sysctl_root.isra.8+0x167 userland_sysctl+0x126 sys___sysctl+0x7b amd64_syscall+0x940 fast_syscall_common+0x101 When I unblocked the failpoints, it completed successfully: $ sudo sysctl debug.fail_point.random_fortuna_pre_read='off' debug.fail_point.random_fortuna_pre_read: return(1) -> off $ sudo sysctl debug.fail_point.random_fortuna_seeded=off debug.fail_point.random_fortuna_seeded: return(1) -> off ... 9e5eb30f Best, ConradReceived on Wed Sep 05 2018 - 01:13:45 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:18 UTC