From: Tobias Stoeckmann Date: Sat, 15 Aug 2020 13:41:41 +0000 (+0200) Subject: Use GRND_NONBLOCK with getrandom. X-Git-Tag: json-c-0.16-20220414~37^2~22^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F657%2Fhead;p=thirdparty%2Fjson-c.git Use GRND_NONBLOCK with getrandom. The json-c library is used in cryptsetup for LUKS2 header information. Since cryptsetup can be called very early during boot, the developers avoid getrandom() calls in their own code base for now. [1] Introducing a blocking getrandom() call in json-c therefore introduces this issue for cryptsetup as well. Even though cryptsetup issues do not have to be json-c issues, here is my proposal: Let's use a non-blocking call, falling back to other sources if the call would block. Since getrandom() accesses urandom, it must mean that we are in an early boot phase -- otherwise the call would not block according to its manual page. As stated in manual page of random(4), accessing /dev/urandom won't block but return weak random numbers, therefore this fallback would work for json-c. While at it, fixed the debug message. [1] https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/47 which references to https://lwn.net/Articles/800509/ --- diff --git a/random_seed.c b/random_seed.c index 17727c6a..c428da9c 100644 --- a/random_seed.c +++ b/random_seed.c @@ -164,19 +164,21 @@ retry: static int get_getrandom_seed(void) { - DEBUG_SEED("get_dev_random_seed"); + DEBUG_SEED("get_getrandom_seed"); int r; ssize_t ret; do { - ret = getrandom(&r, sizeof(r), 0); + ret = getrandom(&r, sizeof(r), GRND_NONBLOCK); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { if (errno == ENOSYS) /* syscall not available in kernel */ return -1; + if (errno == EAGAIN) /* entropy not yet initialized */ + return -1; fprintf(stderr, "error from getrandom(): %s", strerror(errno)); exit(1);