mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
x86/uaccess, sched/preempt: Verify access_ok() context
I recently encountered wreckage because access_ok() was used where it should not be, add an explicit WARN when access_ok() is used wrongly. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
0a21fc1214
commit
7c4788950b
2 changed files with 24 additions and 10 deletions
|
@ -68,6 +68,12 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, 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(unsigned long addr, unsigned long size, 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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue