]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Use GRND_NONBLOCK with getrandom. 657/head
authorTobias Stoeckmann <tobias@stoeckmann.org>
Sat, 15 Aug 2020 13:41:41 +0000 (15:41 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Sat, 15 Aug 2020 13:52:17 +0000 (15:52 +0200)
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/

random_seed.c

index 17727c6a1cff78d28104d8c3c6375f9852d6571c..c428da9c67c6b12f9cf8f49a6d0efb2e6d5f61db 100644 (file)
@@ -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);