futex: Validate futex value against futex size
authorpeterz@infradead.org <peterz@infradead.org>
Thu, 21 Sep 2023 10:45:09 +0000 (12:45 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 21 Sep 2023 17:22:06 +0000 (19:22 +0200)
Ensure the futex value fits in the given futex size. Since this adds a
constraint to an existing syscall, it might possibly change behaviour.

Currently the value would be truncated to a u32 and any high bits
would get silently lost.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20230921105247.828934099@noisy.programming.kicks-ass.net
kernel/futex/futex.h
kernel/futex/syscalls.c

index 68fc052dc09be0c2dba2fa357feb4320c2560aa9..a3f1fceafcbe6cfa73d7223869057edd8f1bb296 100644 (file)
@@ -85,6 +85,16 @@ static inline bool futex_flags_valid(unsigned int flags)
        return true;
 }
 
+static inline bool futex_validate_input(unsigned int flags, u64 val)
+{
+       int bits = 8 * futex_size(flags);
+
+       if (bits < 64 && (val >> bits))
+               return false;
+
+       return true;
+}
+
 #ifdef CONFIG_FAIL_FUTEX
 extern bool should_fail_futex(bool fshared);
 #else
index 948ac247c1c63d45538e7ddc72c2821f2dbad7dc..2339f9ccee7f6ab9c5ca0441e8d147ac0cbfd9e0 100644 (file)
@@ -209,6 +209,9 @@ static int futex_parse_waitv(struct futex_vector *futexv,
                if (!futex_flags_valid(flags))
                        return -EINVAL;
 
+               if (!futex_validate_input(flags, aux.val))
+                       return -EINVAL;
+
                futexv[i].w.flags = flags;
                futexv[i].w.val = aux.val;
                futexv[i].w.uaddr = aux.uaddr;