Patch "x86/uaccess, sched/preempt: Verify access_ok() context" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
x86/uaccess, sched/preempt: Verify access_ok() context
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-uaccess-sched-preempt-verify-access_ok-context.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
7c4788950ba5922fde976d80b72baf46f14dee8dMon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Tue, 22 Nov 2016 10:57:15 +0100
Subject: x86/uaccess, sched/preempt: Verify access_ok() context
From: Peter Zijlstra <[email protected]>
commit 7c4788950ba5922fde976d80b72baf46f14dee8d upstream.
I recently encountered wreckage because access_ok() was used where it should not be, add an explicit WARN when access_ok() is used wrongly.
--- arch/x86/include/asm/uaccess.h | 13 +++++++++++-- include/linux/preempt.h | 21 +++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-)
arch/x86/include/asm/uaccess.h +11 -2
@@ -68,6 +68,12 @@ static inline bool __chk_range_not_ok(un__chk_range_not_ok ((unsigned long __force )(addr), size, limit); \ }) +#ifdef CONFIG_DEBUG_ATOMIC_SLEEP +# define WARN_ON_IN_IRQ () WARN_ON_ONCE(!in_task()) +#else +# define WARN_ON_IN_IRQ () +#endif +/** * access_ok: - Checks if a user space pointer is valid * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
@@ -88,8 +94,11 @@ static inline bool __chk_range_not_ok(un* checks that the pointer is in the user space range - after calling * this function, memory access functions may still return -EFAULT. */ -#define access_ok (type, addr, size) \ - likely(!__range_not_ok(addr, size, user_addr_max())) +#define access_ok (type, addr, size) \ +({ \ + WARN_ON_IN_IRQ(); \ + likely(!__range_not_ok(addr, size, user_addr_max())); \ +})/* * These are the main single-value transfer routines. They automatically
include/linux/preempt.h +13 -8
@@ -65,19 +65,24 @@/* * Are we doing bottom half or hardware interrupt processing? -* Are we in a softirq context? Interrupt context? -* in_softirq - Are we currently processing softirq or have bh disabled? -* in_serving_softirq - Are we currently processing softirq? +* +* in_irq() - We're in (hard) IRQ context +* in_softirq() - We have BH disabled, or are processing softirqs +* in_interrupt() - We're in NMI,IRQ,SoftIRQ context or have BH disabled +* in_serving_softirq() - We're in softirq context +* in_nmi() - We're in NMI context +* in_task() - We're in task context +* +* Note: due to the BH disabled confusion: in_softirq(),in_interrupt() really +* should not be used in new code. */ #define in_irq () (hardirq_count())#define in_softirq () (softirq_count())#define in_interrupt () (irq_count())#define in_serving_softirq () (softirq_count() & SOFTIRQ_OFFSET) - -/* -* Are we in NMI context? -*/ -#define in_nmi () (preempt_count() & NMI_MASK) +#define in_nmi () (preempt_count() & NMI_MASK) +#define in_task () (!(preempt_count() & \ + (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)))/* * The preempt_count offset after preempt_disable();
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/x86-uaccess-sched-preempt-verify-access_ok-context.patch queue-4.9/sched-core-add-missing-update_rq_clock-call-in-sched_move_task.patch queue-4.9/sched-cputime-powerpc32-fix-stale-scaled-stime-on-context-switch.patch