summaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2017-08-24 03:31:05 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-08-25 16:49:59 -0400
commit30d6e0a4190d37740e9447e4e4815f06992dd8c3 (patch)
treeee09f230f291d519765211ba247f16b1634b52f5 /arch/tile
parentca110694c6950dfd7bc864138c80fe39ea43da5b (diff)
futex: Remove duplicated code and fix undefined behaviour
There is code duplicated over all architecture's headers for futex_atomic_op_inuser. Namely op decoding, access_ok check for uaddr, and comparison of the result. Remove this duplication and leave up to the arches only the needed assembly which is now in arch_futex_atomic_op_inuser. This effectively distributes the Will Deacon's arm64 fix for undefined behaviour reported by UBSAN to all architectures. The fix was done in commit 5f16a046f8e1 (arm64: futex: Fix undefined behaviour with FUTEX_OP_OPARG_SHIFT usage). Look there for an example dump. And as suggested by Thomas, check for negative oparg too, because it was also reported to cause undefined behaviour report. Note that s390 removed access_ok check in d12a29703 ("s390/uaccess: remove pointless access_ok() checks") as access_ok there returns true. We introduce it back to the helper for the sake of simplicity (it gets optimized away anyway). Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Russell King <rmk+kernel@armlinux.org.uk> Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc) Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> [s390] Acked-by: Chris Metcalf <cmetcalf@mellanox.com> [for tile] Reviewed-by: Darren Hart (VMware) <dvhart@infradead.org> Reviewed-by: Will Deacon <will.deacon@arm.com> [core/arm64] Cc: linux-mips@linux-mips.org Cc: Rich Felker <dalias@libc.org> Cc: linux-ia64@vger.kernel.org Cc: linux-sh@vger.kernel.org Cc: peterz@infradead.org Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Max Filippov <jcmvbkbc@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: sparclinux@vger.kernel.org Cc: Jonas Bonn <jonas@southpole.se> Cc: linux-s390@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: Yoshinori Sato <ysato@users.sourceforge.jp> Cc: linux-hexagon@vger.kernel.org Cc: Helge Deller <deller@gmx.de> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Matt Turner <mattst88@gmail.com> Cc: linux-snps-arc@lists.infradead.org Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: linux-xtensa@linux-xtensa.org Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> Cc: openrisc@lists.librecores.org Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Stafford Horne <shorne@gmail.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Richard Henderson <rth@twiddle.net> Cc: Chris Zankel <chris@zankel.net> Cc: Michal Simek <monstr@monstr.eu> Cc: Tony Luck <tony.luck@intel.com> Cc: linux-parisc@vger.kernel.org Cc: Vineet Gupta <vgupta@synopsys.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Richard Kuo <rkuo@codeaurora.org> Cc: linux-alpha@vger.kernel.org Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: linuxppc-dev@lists.ozlabs.org Cc: "David S. Miller" <davem@davemloft.net> Link: http://lkml.kernel.org/r/20170824073105.3901-1-jslaby@suse.cz
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/include/asm/futex.h40
1 files changed, 5 insertions, 35 deletions
diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h
index e64a1b75fc38..83c1e639b411 100644
--- a/arch/tile/include/asm/futex.h
+++ b/arch/tile/include/asm/futex.h
@@ -106,12 +106,9 @@
106 lock = __atomic_hashed_lock((int __force *)uaddr) 106 lock = __atomic_hashed_lock((int __force *)uaddr)
107#endif 107#endif
108 108
109static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) 109static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval,
110 u32 __user *uaddr)
110{ 111{
111 int op = (encoded_op >> 28) & 7;
112 int cmp = (encoded_op >> 24) & 15;
113 int oparg = (encoded_op << 8) >> 20;
114 int cmparg = (encoded_op << 20) >> 20;
115 int uninitialized_var(val), ret; 112 int uninitialized_var(val), ret;
116 113
117 __futex_prolog(); 114 __futex_prolog();
@@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
119 /* The 32-bit futex code makes this assumption, so validate it here. */ 116 /* The 32-bit futex code makes this assumption, so validate it here. */
120 BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); 117 BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
121 118
122 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
123 oparg = 1 << oparg;
124
125 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
126 return -EFAULT;
127
128 pagefault_disable(); 119 pagefault_disable();
129 switch (op) { 120 switch (op) {
130 case FUTEX_OP_SET: 121 case FUTEX_OP_SET:
@@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
148 } 139 }
149 pagefault_enable(); 140 pagefault_enable();
150 141
151 if (!ret) { 142 if (!ret)
152 switch (cmp) { 143 *oval = val;
153 case FUTEX_OP_CMP_EQ: 144
154 ret = (val == cmparg);
155 break;
156 case FUTEX_OP_CMP_NE:
157 ret = (val != cmparg);
158 break;
159 case FUTEX_OP_CMP_LT:
160 ret = (val < cmparg);
161 break;
162 case FUTEX_OP_CMP_GE:
163 ret = (val >= cmparg);
164 break;
165 case FUTEX_OP_CMP_LE:
166 ret = (val <= cmparg);
167 break;
168 case FUTEX_OP_CMP_GT:
169 ret = (val > cmparg);
170 break;
171 default:
172 ret = -ENOSYS;
173 }
174 }
175 return ret; 145 return ret;
176} 146}
177 147