random: vDSO: reject unknown getrandom() flags
authorYann Droneaud <yann@droneaud.fr>
Sun, 25 Aug 2024 14:47:50 +0000 (16:47 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 26 Aug 2024 07:58:52 +0000 (09:58 +0200)
Like the getrandom() syscall, vDSO getrandom() must also reject unknown
flags. [1]

It would be possible to return -EINVAL from vDSO itself, but in the
possible case that a new flag is added to getrandom() syscall in the
future, it would be easier to get the behavior from the syscall, instead
of erroring until the vDSO is extended to support the new flag or
explicitly falling back.

[1] Designing the API: Planning for Extension
    https://docs.kernel.org/process/adding-syscalls.html#designing-the-api-planning-for-extension

Signed-off-by: Yann Droneaud <yann@droneaud.fr>
[Jason: reworded commit message]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
lib/vdso/getrandom.c

index b230f0b10832fdb05e0f2703c416c4aae52815b0..e1db228bc4f0d10e0af46112ce0846e5cd95589e 100644 (file)
@@ -85,6 +85,10 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
        if (unlikely(((unsigned long)opaque_state & ~PAGE_MASK) + sizeof(*state) > PAGE_SIZE))
                return -EFAULT;
 
+       /* Handle unexpected flags by falling back to the kernel. */
+       if (unlikely(flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE)))
+               goto fallback_syscall;
+
        /* If the caller passes the wrong size, which might happen due to CRIU, fallback. */
        if (unlikely(opaque_len != sizeof(*state)))
                goto fallback_syscall;