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
| Name | What it does |
|---|---|
| GRND_NONBLOCK | Don't block if the pool isn't initialized (or random source is empty); fail with EAGAIN instead. |
| GRND_RANDOM | Draw from the random source (/dev/random) instead of urandom; may return fewer bytes than asked. |
| GRND_INSECURELinux 5.6 | Return bytes even before the pool is seeded, with no cryptographic guarantee. Early-boot use only. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EAGAIN | Requested entropy wasn't available and GRND_NONBLOCK was set. |
| EINTR | Interrupted by a signal handler; small (<= 256 byte) urandom reads after init don't hit this. |
| EINVAL | Invalid flag in flags. |
| EFAULT | buf points outside the accessible address space. |
| ENOSYS | glibc 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
- getrandom(2), man7.org
- Linux 5.6 (GRND_INSECURE), kernelnewbies
- Linux 6.11 (vDSO getrandom), kernelnewbies
- getrandom(2), FreeBSD
- getentropy(2), OpenBSD
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
