uaccess: fix integer overflow on access_ok()

Three architectures check the end of a user access against the
address limit without taking a possible overflow into account.
Passing a negative length or another overflow in here returns
success when it should not.

Use the most common correct implementation here, which optimizes
for a constant 'size' argument, and turns the common case into a
single comparison.

Cc: stable@vger.kernel.org
Fixes: da55128194 ("csky: User access")
Fixes: f663b60f52 ("microblaze: Fix uaccess_ok macro")
Fixes: 7567746e1c ("Hexagon: Add user access functions")
Reported-by: David Laight <David.Laight@aculab.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann
2022-02-10 16:24:30 +01:00
parent dfd42facf1
commit 222ca305c9
3 changed files with 16 additions and 28 deletions

View File

@@ -3,14 +3,13 @@
#ifndef __ASM_CSKY_UACCESS_H
#define __ASM_CSKY_UACCESS_H
#define user_addr_max() \
(uaccess_kernel() ? KERNEL_DS.seg : get_fs().seg)
#define user_addr_max() (current_thread_info()->addr_limit.seg)
static inline int __access_ok(unsigned long addr, unsigned long size)
{
unsigned long limit = current_thread_info()->addr_limit.seg;
unsigned long limit = user_addr_max();
return ((addr < limit) && ((addr + size) < limit));
return (size <= limit) && (addr <= (limit - size));
}
#define __access_ok __access_ok