GNU bug report logs - #63858
GNU "shuf" on Linux calls getrandom without GRND_NONBLOCK, hangs indefinitely (9.x regression)

Previous Next

Package: coreutils;

Reported by: Nick Bowler <nbowler <at> draconx.ca>

Date: Fri, 2 Jun 2023 19:26:02 UTC

Severity: normal

Full log


Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Nick Bowler <nbowler <at> draconx.ca>
To: bug-coreutils <at> gnu.org
Subject: GNU "shuf" on Linux calls getrandom without GRND_NONBLOCK, hangs
 indefinitely (9.x regression)
Date: Fri, 2 Jun 2023 15:25:07 -0400
Hi,

I installed a new version of GNU coreutils (9.3), and now "shuf" appears
to be blocking on Linux's cryptographic RNG init.  On this particular
machine, there is not a lot of entropy sources so Linux's RNG init takes
an unbounded and potentially very long time.

I hope nobody expects "shuf" to provide cryptographically-secure
randomness (I certainly don't), and it would be nice for shuf to
not hang indefinitely.

Running with strace I see shuf makes two calls to getrandom, the
first passes the GRND_NONBLOCK flag, and shuf appears to fall back to
using clock_gettime in this case, but the second call passes 0 for flags
which means "block until RNG init", and this is the one that hangs.
shuf only makes the second getrandom call if there is actually input
(so shuf </dev/null is OK).

When it is working, after RNG init, strace shows the problematic call
(but it is successful in this case):

  % echo x | strace ./shuf 2>&1 | grep getrandom
  % getrandom("\xd5\x55\xc9\x73", 4, GRND_NONBLOCK) = 4
  % getrandom("\x76", 1, 0)                 = 1

note the 0 flags in the second call.  When it is not working (before RNG
init), the second call hangs indefinitely (killed by a signal in this
case):

  % echo x | strace ./shuf 2>&1
  [...]
  getrandom(0xb6f148c8, 4, GRND_NONBLOCK) = -1 EAGAIN (Resource
temporarily unavailable)
  clock_gettime64(CLOCK_MONOTONIC, 0xbed4e810) = -1 ENOSYS (Function
not implemented)
  clock_gettime(CLOCK_MONOTONIC, {tv_sec=270, tv_nsec=854650394}) = 0
  [...]
  getrandom(0x1c40228, 1, 0)              = ? ERESTARTSYS (To be
restarted if SA_RESTART is set)
  --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
  +++ killed by SIGINT +++

I do not have this problem with coreutils 8.28.  Using the GNU-specific
--random-source=/dev/urandom option is a possible workaround (since
/dev/urandom reads do not block).

Let me know if you need any more info.

Thanks,
  Nick




This bug report was last modified 2 years and 12 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.