[PATCH] arc4random: Fix incorrect usage of TEMP_FAILURE_RETRY
Xi Ruoyao
xry111@xry111.site
Thu Jan 4 00:54:12 GMT 2024
The _nocancel functions returns errors as negative values, i. e. -EINTR
for interrupted system call. But TEMP_FAILURE_RETRY expects the errors
as errno, thus using TEMP_FAILURE_RETRY is incorrect here.
Add a customized TEMP_FAILURE_RETRY_NEG macro and use it instead of
TEMP_FAILURE_RETRY to fix the issue.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
stdlib/arc4random.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c
index 3ae8fc1302..41f24c124c 100644
--- a/stdlib/arc4random.c
+++ b/stdlib/arc4random.c
@@ -30,6 +30,15 @@ arc4random_getrandom_failure (void)
__libc_fatal ("Fatal glibc error: cannot get entropy for arc4random\n");
}
+/* Special version of TEMP_FAILURE_RETRY for error values as negative
+ values. */
+#define TEMP_FAILURE_RETRY_NEG(expression) \
+ (__extension__ \
+ ({ long int __result; \
+ do __result = (long int) (expression); \
+ while (__result == -EINTR); \
+ __result; }))
+
void
__arc4random_buf (void *p, size_t n)
{
@@ -42,7 +51,7 @@ __arc4random_buf (void *p, size_t n)
for (;;)
{
- l = TEMP_FAILURE_RETRY (__getrandom_nocancel (p, n, 0));
+ l = TEMP_FAILURE_RETRY_NEG (__getrandom_nocancel (p, n, 0));
if (l > 0)
{
if ((size_t) l == n)
@@ -60,24 +69,24 @@ __arc4random_buf (void *p, size_t n)
{
/* Poll /dev/random as an approximation of RNG initialization. */
struct pollfd pfd = { .events = POLLIN };
- pfd.fd = TEMP_FAILURE_RETRY (
+ pfd.fd = TEMP_FAILURE_RETRY_NEG (
__open64_nocancel ("/dev/random", O_RDONLY | O_CLOEXEC | O_NOCTTY));
if (pfd.fd < 0)
arc4random_getrandom_failure ();
- if (TEMP_FAILURE_RETRY (__poll_infinity_nocancel (&pfd, 1)) < 0)
+ if (TEMP_FAILURE_RETRY_NEG (__poll_infinity_nocancel (&pfd, 1)) < 0)
arc4random_getrandom_failure ();
if (__close_nocancel (pfd.fd) < 0)
arc4random_getrandom_failure ();
atomic_store_relaxed (&seen_initialized, 1);
}
- fd = TEMP_FAILURE_RETRY (
+ fd = TEMP_FAILURE_RETRY_NEG (
__open64_nocancel ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY));
if (fd < 0)
arc4random_getrandom_failure ();
for (;;)
{
- l = TEMP_FAILURE_RETRY (__read_nocancel (fd, p, n));
+ l = TEMP_FAILURE_RETRY_NEG (__read_nocancel (fd, p, n));
if (l <= 0)
arc4random_getrandom_failure ();
if ((size_t) l == n)
--
2.43.0
More information about the Libc-alpha
mailing list