$RodHat_
Syscall reference · Security

getrandom(2)

Fill a buffer with random bytes from the kernel CSPRNG, without opening /dev/urandom.

Since
Linux 3.17check your kernel →
glibc
glibc 2.25
System
Linux
Man page
getrandom(2)

Synopsis

#include <sys/random.h>

ssize_t getrandom(void buf[size], size_t size, unsigned int flags);

Rod's take

getrandom(2) showed up in Linux 3.17 and fixed the early-boot /dev/urandom mess, but every call still crossed into the kernel and back. The BSDs have done userspace ChaCha20 behind arc4random for years: seed once, generate in-process, reseed when it matters. Linux finally caught up in 6.11 with a vDSO getrandom that keeps per-thread state in userspace and notices fork and reseeds on its own. Fine. Better late than never. For your code nothing changes: ask for small chunks, check the return value every time, and let the default block until the pool is seeded.

Flags and arguments that matter

NameWhat it does
GRND_NONBLOCKDon't block if the pool isn't initialized (or random source is empty); fail with EAGAIN instead.
GRND_RANDOMDraw from the random source (/dev/random) instead of urandom; may return fewer bytes than asked.
GRND_INSECURELinux 5.6Return bytes even before the pool is seeded, with no cryptographic guarantee. Early-boot use only.

Errors you will actually hit

errnoMeaning
EAGAINRequested entropy wasn't available and GRND_NONBLOCK was set.
EINTRInterrupted by a signal handler; small (<= 256 byte) urandom reads after init don't hit this.
EINVALInvalid flag in flags.
EFAULTbuf points outside the accessible address space.
ENOSYSglibc wrapper found the kernel doesn't implement getrandom().

Example

unsigned char nonce[12];
if (getrandom(nonce, sizeof nonce, 0) != (ssize_t)sizeof nonce)
    err(1, "getrandom");

/* early-boot code that must not block */
unsigned char seed[32];
ssize_t n = getrandom(seed, sizeof seed, GRND_NONBLOCK);
if (n == -1 && errno == EAGAIN) {
    /* pool not initialized yet: retry later */
}

Trimmed from the full walkthrough in getrandom(2) without the syscall: what Linux 6.11 finally shipped.

BSD equivalent

FreeBSD: getrandom(2) since FreeBSD 12.0, plus arc4random(3). OpenBSD: getentropy(2) since OpenBSD 5.6; arc4random(3) for bulk use.

The long version, from the console

Sources

  1. getrandom(2), man7.org
  2. Linux 5.6 (GRND_INSECURE), kernelnewbies
  3. Linux 6.11 (vDSO getrandom), kernelnewbies
  4. getrandom(2), FreeBSD
  5. getentropy(2), OpenBSD

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.