* [PATCH 01/14] uaccess: fix integer overflow on access_ok()
[not found] <20220214163452.1568807-1-arnd@kernel.org>
@ 2022-02-14 16:34 ` Arnd Bergmann
2022-02-14 16:58 ` Christoph Hellwig
2022-02-14 16:34 ` [PATCH 03/14] nds32: fix access_ok() checks in get/put_user Arnd Bergmann
1 sibling, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2022-02-14 16:34 UTC (permalink / raw)
To: Linus Torvalds, Christoph Hellwig, linux-arch, linux-mm,
linux-api, arnd, linux-kernel
Cc: linux, will, guoren, bcain, geert, monstr, tsbogend, nickhu,
green.hu, dinguyen, shorne, deller, mpe, peterz, mingo,
mark.rutland, hca, dalias, davem, richard, x86, jcmvbkbc,
ebiederm, akpm, ardb, linux-alpha, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, linux-ia64,
linux-m68k, linux-mips, openrisc, linux-parisc, linuxppc-dev,
linux-riscv, linux-s390, linux-sh, sparclinux, linux-um,
linux-xtensa, stable, David Laight
From: Arnd Bergmann <arnd@arndb.de>
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: da551281947c ("csky: User access")
Fixes: f663b60f5215 ("microblaze: Fix uaccess_ok macro")
Fixes: 7567746e1c0d ("Hexagon: Add user access functions")
Reported-by: David Laight <David.Laight@aculab.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/csky/include/asm/uaccess.h | 7 +++----
arch/hexagon/include/asm/uaccess.h | 18 +++++++++---------
arch/microblaze/include/asm/uaccess.h | 19 ++++---------------
3 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h
index c40f06ee8d3e..ac5a54f57d40 100644
--- a/arch/csky/include/asm/uaccess.h
+++ b/arch/csky/include/asm/uaccess.h
@@ -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
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index ef5bfef8d490..719ba3f3c45c 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -25,17 +25,17 @@
* Returns true (nonzero) if the memory block *may* be valid, false (zero)
* if it is definitely invalid.
*
- * User address space in Hexagon, like x86, goes to 0xbfffffff, so the
- * simple MSB-based tests used by MIPS won't work. Some further
- * optimization is probably possible here, but for now, keep it
- * reasonably simple and not *too* slow. After all, we've got the
- * MMU for backup.
*/
+#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
+#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
-#define __access_ok(addr, size) \
- ((get_fs().seg == KERNEL_DS.seg) || \
- (((unsigned long)addr < get_fs().seg) && \
- (unsigned long)size < (get_fs().seg - (unsigned long)addr)))
+static inline int __access_ok(unsigned long addr, unsigned long size)
+{
+ unsigned long limit = TASK_SIZE;
+
+ return (size <= limit) && (addr <= (limit - size));
+}
+#define __access_ok __access_ok
/*
* When a kernel-mode page fault is taken, the faulting instruction
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index d2a8ef9f8978..5b6e0e7788f4 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -39,24 +39,13 @@
# define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-static inline int access_ok(const void __user *addr, unsigned long size)
+static inline int __access_ok(unsigned long addr, unsigned long size)
{
- if (!size)
- goto ok;
+ unsigned long limit = user_addr_max();
- if ((get_fs().seg < ((unsigned long)addr)) ||
- (get_fs().seg < ((unsigned long)addr + size - 1))) {
- pr_devel("ACCESS fail at 0x%08x (size 0x%x), seg 0x%08x\n",
- (__force u32)addr, (u32)size,
- (u32)get_fs().seg);
- return 0;
- }
-ok:
- pr_devel("ACCESS OK at 0x%08x (size 0x%x), seg 0x%08x\n",
- (__force u32)addr, (u32)size,
- (u32)get_fs().seg);
- return 1;
+ return (size <= limit) && (addr <= (limit - size));
}
+#define access_ok(addr, size) __access_ok((unsigned long)addr, size)
# define __FIXUP_SECTION ".section .fixup,\"ax\"\n"
# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
--
2.29.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 03/14] nds32: fix access_ok() checks in get/put_user
[not found] <20220214163452.1568807-1-arnd@kernel.org>
2022-02-14 16:34 ` [PATCH 01/14] uaccess: fix integer overflow on access_ok() Arnd Bergmann
@ 2022-02-14 16:34 ` Arnd Bergmann
2022-02-14 17:01 ` Christoph Hellwig
1 sibling, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2022-02-14 16:34 UTC (permalink / raw)
To: Linus Torvalds, Christoph Hellwig, linux-arch, linux-mm,
linux-api, arnd, linux-kernel
Cc: linux, will, guoren, bcain, geert, monstr, tsbogend, nickhu,
green.hu, dinguyen, shorne, deller, mpe, peterz, mingo,
mark.rutland, hca, dalias, davem, richard, x86, jcmvbkbc,
ebiederm, akpm, ardb, linux-alpha, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, linux-ia64,
linux-m68k, linux-mips, openrisc, linux-parisc, linuxppc-dev,
linux-riscv, linux-s390, linux-sh, sparclinux, linux-um,
linux-xtensa, stable
From: Arnd Bergmann <arnd@arndb.de>
The get_user()/put_user() functions are meant to check for
access_ok(), while the __get_user()/__put_user() functions
don't.
This broke in 4.19 for nds32, when it gained an extraneous
check in __get_user(), but lost the check it needs in
__put_user().
Fixes: 487913ab18c2 ("nds32: Extract the checking and getting pointer to a macro")
Cc: stable@vger.kernel.org @ v4.19+
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/nds32/include/asm/uaccess.h | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h
index d4cbf069dc22..37a40981deb3 100644
--- a/arch/nds32/include/asm/uaccess.h
+++ b/arch/nds32/include/asm/uaccess.h
@@ -70,9 +70,7 @@ static inline void set_fs(mm_segment_t fs)
* versions are void (ie, don't return a value as such).
*/
-#define get_user __get_user \
-
-#define __get_user(x, ptr) \
+#define get_user(x, ptr) \
({ \
long __gu_err = 0; \
__get_user_check((x), (ptr), __gu_err); \
@@ -85,6 +83,14 @@ static inline void set_fs(mm_segment_t fs)
(void)0; \
})
+#define __get_user(x, ptr) \
+({ \
+ long __gu_err = 0; \
+ const __typeof__(*(ptr)) __user *__p = (ptr); \
+ __get_user_err((x), __p, (__gu_err)); \
+ __gu_err; \
+})
+
#define __get_user_check(x, ptr, err) \
({ \
const __typeof__(*(ptr)) __user *__p = (ptr); \
@@ -165,12 +171,18 @@ do { \
: "r"(addr), "i"(-EFAULT) \
: "cc")
-#define put_user __put_user \
+#define put_user(x, ptr) \
+({ \
+ long __pu_err = 0; \
+ __put_user_check((x), (ptr), __pu_err); \
+ __pu_err; \
+})
#define __put_user(x, ptr) \
({ \
long __pu_err = 0; \
- __put_user_err((x), (ptr), __pu_err); \
+ __typeof__(*(ptr)) __user *__p = (ptr); \
+ __put_user_err((x), __p, __pu_err); \
__pu_err; \
})
--
2.29.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 01/14] uaccess: fix integer overflow on access_ok()
2022-02-14 16:34 ` [PATCH 01/14] uaccess: fix integer overflow on access_ok() Arnd Bergmann
@ 2022-02-14 16:58 ` Christoph Hellwig
0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2022-02-14 16:58 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, Christoph Hellwig, linux-arch, linux-mm,
linux-api, arnd, linux-kernel, mark.rutland, dalias, linux-ia64,
linux-sh, peterz, jcmvbkbc, guoren, sparclinux, linux-hexagon,
linux-riscv, will, ardb, linux-s390, bcain, deller, x86, linux,
linux-csky, mingo, geert, linux-snps-arc, linux-xtensa, hca,
linux-alpha, linux-um, linux-m68k, openrisc, green.hu, shorne,
linux-arm-kernel, monstr, tsbogend, linux-parisc, nickhu,
linux-mips, stable, dinguyen, David Laight, ebiederm, richard,
akpm, linuxppc-dev, davem
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 03/14] nds32: fix access_ok() checks in get/put_user
2022-02-14 16:34 ` [PATCH 03/14] nds32: fix access_ok() checks in get/put_user Arnd Bergmann
@ 2022-02-14 17:01 ` Christoph Hellwig
2022-02-14 17:10 ` David Laight
2022-02-15 9:18 ` Arnd Bergmann
0 siblings, 2 replies; 7+ messages in thread
From: Christoph Hellwig @ 2022-02-14 17:01 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, Christoph Hellwig, linux-arch, linux-mm,
linux-api, arnd, linux-kernel, mark.rutland, dalias, linux-ia64,
linux-sh, peterz, jcmvbkbc, guoren, sparclinux, linux-hexagon,
linux-riscv, will, ardb, linux-s390, bcain, deller, x86, linux,
linux-csky, mingo, geert, linux-snps-arc, linux-xtensa, hca,
linux-alpha, linux-um, linux-m68k, openrisc, green.hu, shorne,
linux-arm-kernel, monstr, tsbogend, linux-parisc, nickhu,
linux-mips, stable, dinguyen, ebiederm, richard, akpm,
linuxppc-dev, davem
On Mon, Feb 14, 2022 at 05:34:41PM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The get_user()/put_user() functions are meant to check for
> access_ok(), while the __get_user()/__put_user() functions
> don't.
>
> This broke in 4.19 for nds32, when it gained an extraneous
> check in __get_user(), but lost the check it needs in
> __put_user().
Can we follow the lead of MIPS (which this was originally copied
from I think) and kill the pointless __get/put_user_check wrapper
that just obsfucate the code?
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH 03/14] nds32: fix access_ok() checks in get/put_user
2022-02-14 17:01 ` Christoph Hellwig
@ 2022-02-14 17:10 ` David Laight
2022-02-15 9:18 ` Arnd Bergmann
1 sibling, 0 replies; 7+ messages in thread
From: David Laight @ 2022-02-14 17:10 UTC (permalink / raw)
To: 'Christoph Hellwig', Arnd Bergmann
Cc: Linus Torvalds, Christoph Hellwig, linux-arch@vger.kernel.org,
linux-mm@kvack.org, linux-api@vger.kernel.org, arnd@arndb.de,
linux-kernel@vger.kernel.org, mark.rutland@arm.com,
dalias@libc.org, linux-ia64@vger.kernel.org,
linux-sh@vger.kernel.org, peterz@infradead.org,
jcmvbkbc@gmail.com, guoren@kernel.org, sparclinux@vger.kernel.org,
linux-hexagon@vger.kernel.org, linux-riscv@lists.infradead.org,
will@kernel.org, ardb@kernel.org, linux-s390@vger.kernel.org,
bcain@codeaurora.org, deller@gmx.de, x86@kernel.org,
linux@armlinux.org.uk, linux-csky@vger.kernel.org,
mingo@redhat.com, geert@linux-m68k.org,
linux-snps-arc@lists.infradead.org, linux-xtensa@linux-xtensa.org,
hca@linux.ibm.com, linux-alpha@vger.kernel.org,
linux-um@lists.infradead.org, linux-m68k@lists.linux-m68k.org,
openrisc@lists.librecores.org, green.hu@gmail.com,
shorne@gmail.com, linux-arm-kernel@lists.infradead.org,
monstr@monstr.eu, tsbogend@alpha.franken.de,
linux-parisc@vger.kernel.org, nickhu@andestech.com,
linux-mips@vger.kernel.org, stable@vger.kernel.org,
dinguyen@kernel.org, ebiederm@xmission.com, richard@nod.at,
akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org,
davem@davemloft.net
From: Christoph Hellwig
> Sent: 14 February 2022 17:01
>
> On Mon, Feb 14, 2022 at 05:34:41PM +0100, Arnd Bergmann wrote:
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > The get_user()/put_user() functions are meant to check for
> > access_ok(), while the __get_user()/__put_user() functions
> > don't.
> >
> > This broke in 4.19 for nds32, when it gained an extraneous
> > check in __get_user(), but lost the check it needs in
> > __put_user().
>
> Can we follow the lead of MIPS (which this was originally copied
> from I think) and kill the pointless __get/put_user_check wrapper
> that just obsfucate the code?
Is it possible to make all these architectures fall back to
a common definition somewhere?
Maybe they need to define ACCESS_OK_USER_LIMIT - which can be
different from TASK_SIZE.
There'll be a few special cases, but most architectures have
kernel addresses above userspace ones.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 03/14] nds32: fix access_ok() checks in get/put_user
2022-02-14 17:01 ` Christoph Hellwig
2022-02-14 17:10 ` David Laight
@ 2022-02-15 9:18 ` Arnd Bergmann
2022-02-15 10:25 ` Greg KH
1 sibling, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2022-02-15 9:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Linus Torvalds, Christoph Hellwig, linux-arch, Linux-MM,
Linux API, Arnd Bergmann, Linux Kernel Mailing List, Mark Rutland,
Rich Felker, linux-ia64, Linux-sh list, Peter Zijlstra,
Max Filippov, Guo Ren, sparclinux, open list:QUALCOMM HEXAGON...,
linux-riscv, Will Deacon, Ard Biesheuvel, linux-s390, Brian Cain,
Helge Deller, the arch/x86 maintainers, Russell King - ARM Linux,
linux-csky, Ingo Molnar, Geert Uytterhoeven,
open list:SYNOPSYS ARC ARCHITECTURE,
open list:TENSILICA XTENSA PORT (xtensa), Heiko Carstens, alpha,
linux-um, linux-m68k, Openrisc, Greentime Hu, Stafford Horne,
Linux ARM, Michal Simek, Thomas Bogendoerfer, Parisc List,
Nick Hu, open list:BROADCOM NVRAM DRIVER, # 3.4.x, Dinh Nguyen,
Eric W . Biederman, Richard Weinberger, Andrew Morton,
linuxppc-dev, David Miller
On Mon, Feb 14, 2022 at 6:01 PM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Mon, Feb 14, 2022 at 05:34:41PM +0100, Arnd Bergmann wrote:
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > The get_user()/put_user() functions are meant to check for
> > access_ok(), while the __get_user()/__put_user() functions
> > don't.
> >
> > This broke in 4.19 for nds32, when it gained an extraneous
> > check in __get_user(), but lost the check it needs in
> > __put_user().
>
> Can we follow the lead of MIPS (which this was originally copied
> from I think) and kill the pointless __get/put_user_check wrapper
> that just obsfucate the code?
I had another look, but I think that would be a bigger change than
I want to have in a fix for stable backports, as nds32 also uses
the _check versions in __{get,put}_user_error.
If we instead clean it up in a separate patch, it should be done for
all eight architectures that do the same thing, but at that point,
the time seems better spent at coming up with a new set of
calling conventions that work with asm-goto.
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 03/14] nds32: fix access_ok() checks in get/put_user
2022-02-15 9:18 ` Arnd Bergmann
@ 2022-02-15 10:25 ` Greg KH
0 siblings, 0 replies; 7+ messages in thread
From: Greg KH @ 2022-02-15 10:25 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Christoph Hellwig, Linus Torvalds, Christoph Hellwig, linux-arch,
Linux-MM, Linux API, Arnd Bergmann, Linux Kernel Mailing List,
Mark Rutland, Rich Felker, linux-ia64, Linux-sh list,
Peter Zijlstra, Max Filippov, Guo Ren, sparclinux,
open list:QUALCOMM HEXAGON..., linux-riscv, Will Deacon,
Ard Biesheuvel, linux-s390, Brian Cain, Helge Deller,
the arch/x86 maintainers, Russell King - ARM Linux, linux-csky,
Ingo Molnar, Geert Uytterhoeven,
open list:SYNOPSYS ARC ARCHITECTURE,
open list:TENSILICA XTENSA PORT (xtensa), Heiko Carstens, alpha,
linux-um, linux-m68k, Openrisc, Greentime Hu, Stafford Horne,
Linux ARM, Michal Simek, Thomas Bogendoerfer, Parisc List,
Nick Hu, open list:BROADCOM NVRAM DRIVER, # 3.4.x, Dinh Nguyen,
Eric W . Biederman, Richard Weinberger, Andrew Morton,
linuxppc-dev, David Miller
On Tue, Feb 15, 2022 at 10:18:15AM +0100, Arnd Bergmann wrote:
> On Mon, Feb 14, 2022 at 6:01 PM Christoph Hellwig <hch@infradead.org> wrote:
> >
> > On Mon, Feb 14, 2022 at 05:34:41PM +0100, Arnd Bergmann wrote:
> > > From: Arnd Bergmann <arnd@arndb.de>
> > >
> > > The get_user()/put_user() functions are meant to check for
> > > access_ok(), while the __get_user()/__put_user() functions
> > > don't.
> > >
> > > This broke in 4.19 for nds32, when it gained an extraneous
> > > check in __get_user(), but lost the check it needs in
> > > __put_user().
> >
> > Can we follow the lead of MIPS (which this was originally copied
> > from I think) and kill the pointless __get/put_user_check wrapper
> > that just obsfucate the code?
>
> I had another look, but I think that would be a bigger change than
> I want to have in a fix for stable backports, as nds32 also uses
> the _check versions in __{get,put}_user_error.
Don't worry about stable backports first, get it correct and merged and
then worry about them if you really have to.
If someone cares about nds32 for stable kernels, they can do the
backport work :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-02-15 10:25 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20220214163452.1568807-1-arnd@kernel.org>
2022-02-14 16:34 ` [PATCH 01/14] uaccess: fix integer overflow on access_ok() Arnd Bergmann
2022-02-14 16:58 ` Christoph Hellwig
2022-02-14 16:34 ` [PATCH 03/14] nds32: fix access_ok() checks in get/put_user Arnd Bergmann
2022-02-14 17:01 ` Christoph Hellwig
2022-02-14 17:10 ` David Laight
2022-02-15 9:18 ` Arnd Bergmann
2022-02-15 10:25 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox