Commit 43adf844 authored by peterz@infradead.org's avatar peterz@infradead.org Committed by Peter Zijlstra

futex: FLAGS_STRICT

The current semantics for futex_wake() are a bit loose, specifically
asking for 0 futexes to be woken actually gets you 1.

Adding a !nr check to sys_futex_wake() makes that it would return 0
for unaligned futex words, because that check comes in the shared
futex_wake() function. Adding the !nr check there, would affect the
legacy sys_futex() semantics.

Hence frob a flag :-(
Suggested-by: default avatarAndré Almeida <andrealmeid@igalia.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20230921105248.048643656@noisy.programming.kicks-ass.net
parent 9f6c532f
...@@ -17,25 +17,26 @@ ...@@ -17,25 +17,26 @@
* Futex flags used to encode options to functions and preserve them across * Futex flags used to encode options to functions and preserve them across
* restarts. * restarts.
*/ */
#define FLAGS_SIZE_8 0x00 #define FLAGS_SIZE_8 0x0000
#define FLAGS_SIZE_16 0x01 #define FLAGS_SIZE_16 0x0001
#define FLAGS_SIZE_32 0x02 #define FLAGS_SIZE_32 0x0002
#define FLAGS_SIZE_64 0x03 #define FLAGS_SIZE_64 0x0003
#define FLAGS_SIZE_MASK 0x03 #define FLAGS_SIZE_MASK 0x0003
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
# define FLAGS_SHARED 0x10 # define FLAGS_SHARED 0x0010
#else #else
/* /*
* NOMMU does not have per process address space. Let the compiler optimize * NOMMU does not have per process address space. Let the compiler optimize
* code away. * code away.
*/ */
# define FLAGS_SHARED 0x00 # define FLAGS_SHARED 0x0000
#endif #endif
#define FLAGS_CLOCKRT 0x20 #define FLAGS_CLOCKRT 0x0020
#define FLAGS_HAS_TIMEOUT 0x40 #define FLAGS_HAS_TIMEOUT 0x0040
#define FLAGS_NUMA 0x80 #define FLAGS_NUMA 0x0080
#define FLAGS_STRICT 0x0100
/* FUTEX_ to FLAGS_ */ /* FUTEX_ to FLAGS_ */
static inline unsigned int futex_to_flags(unsigned int op) static inline unsigned int futex_to_flags(unsigned int op)
......
...@@ -333,7 +333,7 @@ SYSCALL_DEFINE4(futex_wake, ...@@ -333,7 +333,7 @@ SYSCALL_DEFINE4(futex_wake,
if (!futex_validate_input(flags, mask)) if (!futex_validate_input(flags, mask))
return -EINVAL; return -EINVAL;
return futex_wake(uaddr, flags, nr, mask); return futex_wake(uaddr, FLAGS_STRICT | flags, nr, mask);
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
...@@ -155,6 +155,9 @@ int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) ...@@ -155,6 +155,9 @@ int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset)
if (unlikely(ret != 0)) if (unlikely(ret != 0))
return ret; return ret;
if ((flags & FLAGS_STRICT) && !nr_wake)
return 0;
hb = futex_hash(&key); hb = futex_hash(&key);
/* Make sure we really have tasks to wakeup */ /* Make sure we really have tasks to wakeup */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment