mirror of
https://github.com/json-c/json-c.git
synced 2026-04-06 22:09:06 +08:00
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/
This commit is contained in:
@@ -164,19 +164,21 @@ retry:
|
|||||||
|
|
||||||
static int get_getrandom_seed(void)
|
static int get_getrandom_seed(void)
|
||||||
{
|
{
|
||||||
DEBUG_SEED("get_dev_random_seed");
|
DEBUG_SEED("get_getrandom_seed");
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = getrandom(&r, sizeof(r), 0);
|
ret = getrandom(&r, sizeof(r), GRND_NONBLOCK);
|
||||||
} while ((ret == -1) && (errno == EINTR));
|
} while ((ret == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
if (errno == ENOSYS) /* syscall not available in kernel */
|
if (errno == ENOSYS) /* syscall not available in kernel */
|
||||||
return -1;
|
return -1;
|
||||||
|
if (errno == EAGAIN) /* entropy not yet initialized */
|
||||||
|
return -1;
|
||||||
|
|
||||||
fprintf(stderr, "error from getrandom(): %s", strerror(errno));
|
fprintf(stderr, "error from getrandom(): %s", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user