]> git.itanic.dy.fi Git - linux-stable/commit
iov_iter: remove uaccess_kernel() warning from iov_iter_init()
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Jul 2021 23:12:42 +0000 (16:12 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Jul 2021 23:12:42 +0000 (16:12 -0700)
commita180bd1d7e16173d965b263c5a536aa40afa2a2a
tree2c7847f2e33922ae069f85947ed1b0c5d104ee8b
parent28e92f990337b8b4c5fdec47667f8b96089c503e
iov_iter: remove uaccess_kernel() warning from iov_iter_init()

This warning was there to catch any architectures that still use
CONFIG_SET_FS, and that would mis-use iov_iter_init() for anything that
wasn't a proper user space pointer.  So that

        WARN_ON_ONCE(uaccess_kernel());

makes perfect conceptual sense: you really shouldn't use a kernel
pointer with set_fs(KERNEL_DS) and then pass it to iov_iter_init().

HOWEVER.

Guenter Roeck reports that this warning actually triggers in no-mmu
configurations of both ARM and m68k.  And the reason isn't that they
pass in a kernel pointer under set_fs(KERNEL_DS) at all: the reason is
that in those configurations, "uaccess_kernel()" is simply not reliable.

Those no-mmu setups set USER_DS and KERNEL_DS to the same values, so you
can't test for the difference.

In particular, the no-mmu case for ARM does

   #define USER_DS                 KERNEL_DS
   #define uaccess_kernel()        (true)

so USER_DS and KERNEL_DS have the same value, and uaccess_kernel() is
always trivially true.

The m68k case is slightly different and not quite as obvious.  It does
(spread out over multiple header files just to be extra exciting:
asm/processor.h, asm/segment.h and asm-generic/uaccess.h):

   #define TASK_SIZE       (0xFFFFFFFFUL)
   #define USER_DS         MAKE_MM_SEG(TASK_SIZE)
   #define KERNEL_DS       MAKE_MM_SEG(~0UL)
   #define get_fs()        (current_thread_info()->addr_limit)
   #define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)

but the end result is the same: uaccess_kernel() will always be true,
because USER_DS and KERNEL_DS end up having the same value, even if that
value is defined differently.

This is very arguably a misfeature in those implementations, but in the
end we don't really care.  All modern architectures have gotten rid of
set_fs() already, and generic kernel code never uses it.  And while the
sanity check was a nice idea, an architecture would have to go the extra
mile to actually break this.

So this well-intentioned warning isn't really all that likely to find
anything but these known false positives, and as such just isn't worth
maintaining.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Fixes: 8cd54c1c8480 ("iov_iter: separate direction from flavour")
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
lib/iov_iter.c