Commit a180bd1d authored by Linus Torvalds's avatar Linus Torvalds

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: default avatarGuenter Roeck <linux@roeck-us.net>
Fixes: 8cd54c1c ("iov_iter: separate direction from flavour")
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 28e92f99
...@@ -465,7 +465,6 @@ void iov_iter_init(struct iov_iter *i, unsigned int direction, ...@@ -465,7 +465,6 @@ void iov_iter_init(struct iov_iter *i, unsigned int direction,
size_t count) size_t count)
{ {
WARN_ON(direction & ~(READ | WRITE)); WARN_ON(direction & ~(READ | WRITE));
WARN_ON_ONCE(uaccess_kernel());
*i = (struct iov_iter) { *i = (struct iov_iter) {
.iter_type = ITER_IOVEC, .iter_type = ITER_IOVEC,
.data_source = direction, .data_source = direction,
......
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