Commit 6ccdc91d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

x86: mm: remove architecture-specific 'access_ok()' define



There's already a generic definition of 'access_ok()' in the
asm-generic/access_ok.h header file, and the only difference bwteen that
and the x86-specific one is the added check for WARN_ON_IN_IRQ().

And it turns out that the reason for that check is long gone: it used to
use a "user_addr_max()" inline function that depended on the current
thread, and caused problems in non-thread contexts.

For details, see commits 7c478895 ("x86/uaccess, sched/preempt:
Verify access_ok() context") and in particular commit ae31fe51
("perf/x86: Restore TASK_SIZE check on frame pointer") about how and why
this came to be.

But that "current task" issue was removed in the big set_fs() removal by
Christoph Hellwig in commit 47058bb5 ("x86: remove address space
overrides using set_fs()").

So the reason for the test and the architecture-specific access_ok()
define no longer exists, and is actually harmful these days.  For
example, it led various 'copy_from_user_nmi()' games (eg using
__range_not_ok() instead, and then later converted to __access_ok() when
that became ok).

And that in turn meant that LAM was broken for the frame following
before this series, because __access_ok() used to not do the address
untagging.

Accessing user state still needs care in many contexts, but access_ok()
is not the place for this test.

Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6014bc27
Loading
Loading
Loading
Loading
+0 −34
Original line number Diff line number Diff line
@@ -16,14 +16,6 @@
#include <asm/extable.h>
#include <asm/tlbflush.h>

#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
static inline bool pagefault_disabled(void);
# define WARN_ON_IN_IRQ()	\
	WARN_ON_ONCE(!in_task() && !pagefault_disabled())
#else
# define WARN_ON_IN_IRQ()
#endif

#ifdef CONFIG_ADDRESS_MASKING
/*
 * Mask out tag bits from the address.
@@ -103,32 +95,6 @@ static inline bool __access_ok(const void __user *ptr, unsigned long size)
#define __access_ok __access_ok
#endif

/**
 * access_ok - Checks if a user space pointer is valid
 * @addr: User space pointer to start of block to check
 * @size: Size of block to check
 *
 * Context: User context only. This function may sleep if pagefaults are
 *          enabled.
 *
 * Checks if a pointer to a block of memory in user space is valid.
 *
 * Note that, depending on architecture, this function probably just
 * checks that the pointer is in the user space range - after calling
 * this function, memory access functions may still return -EFAULT.
 *
 * Return: true (nonzero) if the memory block may be valid, false (zero)
 * if it is definitely invalid.
 *
 * This should not be x86-specific. The only odd things out here is
 * the WARN_ON_IN_IRQ(), which doesn't exist in the generic version.
 */
#define access_ok(addr, size)			\
({						\
	WARN_ON_IN_IRQ();			\
	likely(__access_ok(addr, size));	\
})

#include <asm-generic/access_ok.h>

extern int __get_user_1(void);