diff options
author | Hiago De Franco <hiago.franco@toradex.com> | 2025-01-13 20:31:40 -0300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2025-01-21 12:07:56 +0000 |
commit | e330214c2c4c16a0ce6e872db42b08e093a6de1d (patch) | |
tree | ed25736d35155584ba22361df922ebe87bd6b1d2 /meta/recipes-core | |
parent | 15d005ccbfad08c76cc523ca3f438ae5ce50cfa2 (diff) | |
download | poky-e330214c2c4c16a0ce6e872db42b08e093a6de1d.tar.gz |
eudev: backport patch to fix udevd hanging while trying to access /dev/urandom
Linux kernel commit 48bff1053c17 ("random: opportunistically initialize
on /dev/urandom reads") introduced a change where /dev/urandom blocks if
the random pool is insufficiently initialized during hardware boot. This
behavior causes /dev/urandom reads to hang for approximately 5 seconds,
delaying the boot process with eudev init script (when it calls udevd).
This issue has already been solved upstream, therefore backport the
upstream patch to fix this.
(From OE-Core rev: cd5f630581f3e38645a92ad75b496bce92b679cb)
Signed-off-by: Hiago De Franco <hiago.franco@toradex.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core')
-rw-r--r-- | meta/recipes-core/udev/eudev/0001-random-util.c-sync-dev_urandom-implementation-to-sys.patch | 138 | ||||
-rw-r--r-- | meta/recipes-core/udev/eudev_3.2.14.bb | 1 |
2 files changed, 139 insertions, 0 deletions
diff --git a/meta/recipes-core/udev/eudev/0001-random-util.c-sync-dev_urandom-implementation-to-sys.patch b/meta/recipes-core/udev/eudev/0001-random-util.c-sync-dev_urandom-implementation-to-sys.patch new file mode 100644 index 0000000000..668aa731ac --- /dev/null +++ b/meta/recipes-core/udev/eudev/0001-random-util.c-sync-dev_urandom-implementation-to-sys.patch | |||
@@ -0,0 +1,138 @@ | |||
1 | From 95c871b7b912f39539777ac222ef7f8798bb0225 Mon Sep 17 00:00:00 2001 | ||
2 | From: Masahisa Kojima <kojima.masahisa@socionext.com> | ||
3 | Date: Thu, 25 Apr 2024 17:23:10 +0900 | ||
4 | Subject: [PATCH] random-util.c: sync dev_urandom implementation to | ||
5 | systemd-udev | ||
6 | |||
7 | Current dev_urandom() assumes that reading /dev/urandom | ||
8 | will never block regardless if the random pool is fully | ||
9 | initialized or not. | ||
10 | This assumption is no longer applicable since linux kerrnel | ||
11 | enforces the /dev/urandom entropy initialization from | ||
12 | v5.18-rc2 with the commit: | ||
13 | 48bff1053c17 ("random: opportunistically initialize on /dev/urandom reads"). | ||
14 | |||
15 | With this, when we use the linux v5.18-rc2 or later, | ||
16 | dev_urandom() will block if enough random pool is not supplied. | ||
17 | It causes the boot delay, typically 1024msec(4msec * 256 = 1024msec) | ||
18 | delay to fill the 256 bits entropy for the case CONFIG_HZ=250. | ||
19 | |||
20 | To prevent this boot delay, this commit syncs dev_urandom() | ||
21 | implementation to the systemd-udev. | ||
22 | The systemd-udev implementation of reading /dev/urandom is as follows. | ||
23 | - Try to get random with calling getrandom(GRND_INSECURE) | ||
24 | - If kernel does not support GRND_INSECURE, fallback to GRND_NONBLOCK | ||
25 | - If enough entropy is not supplied, fallback to reading /dev/urandom, | ||
26 | this will block when the kernel version is v5.18-rc2 or later | ||
27 | |||
28 | With this modification, dev_urandom() tries not to block | ||
29 | as much as possible. | ||
30 | |||
31 | This modification still keeps the backword compatibility, | ||
32 | dev_random() will never block if the commit(48bff1053c17) is not | ||
33 | applied to the linux kernel, the behavior is same as before | ||
34 | in this case. | ||
35 | |||
36 | Upstream-Status: Backport [a49a3aaa460add6ae7ea208b4cac630e56fe1180] | ||
37 | Signed-off-by: Masahisa Kojima <kojima.masahisa@socionext.com> | ||
38 | --- | ||
39 | src/shared/missing.h | 4 +++ | ||
40 | src/shared/random-util.c | 70 ++++++++++++++++++---------------------- | ||
41 | 2 files changed, 35 insertions(+), 39 deletions(-) | ||
42 | |||
43 | diff --git a/src/shared/missing.h b/src/shared/missing.h | ||
44 | index 1967840cdbf3..1caec0f9207c 100644 | ||
45 | --- a/src/shared/missing.h | ||
46 | +++ b/src/shared/missing.h | ||
47 | @@ -79,6 +79,10 @@ static inline int getrandom(void *buffer, size_t count, unsigned flags) { | ||
48 | #define GRND_RANDOM 0x0002 | ||
49 | #endif | ||
50 | |||
51 | +#ifndef GRND_INSECURE | ||
52 | +#define GRND_INSECURE 0x0004 | ||
53 | +#endif | ||
54 | + | ||
55 | #ifndef BTRFS_IOCTL_MAGIC | ||
56 | #define BTRFS_IOCTL_MAGIC 0x94 | ||
57 | #endif | ||
58 | diff --git a/src/shared/random-util.c b/src/shared/random-util.c | ||
59 | index 01a28c8ef4e9..852b00e4ce2b 100644 | ||
60 | --- a/src/shared/random-util.c | ||
61 | +++ b/src/shared/random-util.c | ||
62 | @@ -31,45 +31,37 @@ | ||
63 | #include "util.h" | ||
64 | |||
65 | int dev_urandom(void *p, size_t n) { | ||
66 | - static int have_syscall = -1; | ||
67 | - | ||
68 | - _cleanup_close_ int fd = -1; | ||
69 | - int r; | ||
70 | - | ||
71 | - /* Gathers some randomness from the kernel. This call will | ||
72 | - * never block, and will always return some data from the | ||
73 | - * kernel, regardless if the random pool is fully initialized | ||
74 | - * or not. It thus makes no guarantee for the quality of the | ||
75 | - * returned entropy, but is good enough for or usual usecases | ||
76 | - * of seeding the hash functions for hashtable */ | ||
77 | - | ||
78 | - /* Use the getrandom() syscall unless we know we don't have | ||
79 | - * it, or when the requested size is too large for it. */ | ||
80 | - if (have_syscall != 0 || (size_t) (int) n != n) { | ||
81 | - r = getrandom(p, n, GRND_NONBLOCK); | ||
82 | - if (r == (int) n) { | ||
83 | - have_syscall = true; | ||
84 | - return 0; | ||
85 | - } | ||
86 | - | ||
87 | - if (r < 0) { | ||
88 | - if (errno == ENOSYS) | ||
89 | - /* we lack the syscall, continue with | ||
90 | - * reading from /dev/urandom */ | ||
91 | - have_syscall = false; | ||
92 | - else if (errno == EAGAIN) | ||
93 | - /* not enough entropy for now. Let's | ||
94 | - * remember to use the syscall the | ||
95 | - * next time, again, but also read | ||
96 | - * from /dev/urandom for now, which | ||
97 | - * doesn't care about the current | ||
98 | - * amount of entropy. */ | ||
99 | - have_syscall = true; | ||
100 | - else | ||
101 | - return -errno; | ||
102 | - } else | ||
103 | - /* too short read? */ | ||
104 | - return -ENODATA; | ||
105 | + static bool have_getrandom = true, have_grndinsecure = true; | ||
106 | + _cleanup_close_ int fd = -EBADF; | ||
107 | + | ||
108 | + if (n == 0) | ||
109 | + return 0; | ||
110 | + | ||
111 | + for (;;) { | ||
112 | + ssize_t l; | ||
113 | + | ||
114 | + if (!have_getrandom) | ||
115 | + break; | ||
116 | + | ||
117 | + l = getrandom(p, n, have_grndinsecure ? GRND_INSECURE : GRND_NONBLOCK); | ||
118 | + if (l > 0) { | ||
119 | + if ((size_t) l == n) | ||
120 | + return 0; /* Done reading, success. */ | ||
121 | + p = (uint8_t *) p + l; | ||
122 | + n -= l; | ||
123 | + continue; /* Interrupted by a signal; keep going. */ | ||
124 | + } else if (l == 0) | ||
125 | + break; /* Weird, so fallback to /dev/urandom. */ | ||
126 | + else if (errno == ENOSYS) { | ||
127 | + have_getrandom = false; | ||
128 | + break; /* No syscall, so fallback to /dev/urandom. */ | ||
129 | + } else if (errno == EINVAL && have_grndinsecure) { | ||
130 | + have_grndinsecure = false; | ||
131 | + continue; /* No GRND_INSECURE; fallback to GRND_NONBLOCK. */ | ||
132 | + } else if (errno == EAGAIN && !have_grndinsecure) | ||
133 | + break; /* Will block, but no GRND_INSECURE, so fallback to /dev/urandom. */ | ||
134 | + | ||
135 | + break; /* Unexpected, so just give up and fallback to /dev/urandom. */ | ||
136 | } | ||
137 | |||
138 | fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); | ||
diff --git a/meta/recipes-core/udev/eudev_3.2.14.bb b/meta/recipes-core/udev/eudev_3.2.14.bb index 0e5610f77c..b3e7d092c5 100644 --- a/meta/recipes-core/udev/eudev_3.2.14.bb +++ b/meta/recipes-core/udev/eudev_3.2.14.bb | |||
@@ -13,6 +13,7 @@ SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/${BP}.tar.gz \ | |||
13 | file://netifnames.patch \ | 13 | file://netifnames.patch \ |
14 | file://init \ | 14 | file://init \ |
15 | file://local.rules \ | 15 | file://local.rules \ |
16 | file://0001-random-util.c-sync-dev_urandom-implementation-to-sys.patch \ | ||
16 | " | 17 | " |
17 | 18 | ||
18 | SRC_URI[sha256sum] = "8da4319102f24abbf7fff5ce9c416af848df163b29590e666d334cc1927f006f" | 19 | SRC_URI[sha256sum] = "8da4319102f24abbf7fff5ce9c416af848df163b29590e666d334cc1927f006f" |