mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
hrtimer: Don't dereference the hrtimer pointer after the callback
A hrtimer can be released in its callback, but lockdep_hrtimer_exit() dereferences the pointer after the callback returns, i.e. a potential use after free. Retrieve the context in which the hrtimer expires before the callback is invoked and use it in lockdep_hrtimer_exit(). Fixes: 40db173965c0 ("lockdep: Add hrtimer context tracing bits") Reported-by: syzbot+62c155c276e580cfb606@syzkaller.appspotmail.com Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/r/20200331201849.fkp2siy3vcdqvqlz@linutronix.de Signed-off-by: celtare21 <celtare21@gmail.com> Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
parent
51af9ff14e
commit
1607023333
@ -47,16 +47,21 @@ do { \
|
||||
# define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1,
|
||||
|
||||
# define lockdep_hrtimer_enter(__hrtimer) \
|
||||
do { \
|
||||
if (!__hrtimer->is_hard) \
|
||||
current->irq_config = 1; \
|
||||
} while (0)
|
||||
({ \
|
||||
bool __expires_hardirq = true; \
|
||||
\
|
||||
if (!__hrtimer->is_hard) { \
|
||||
current->irq_config = 1; \
|
||||
__expires_hardirq = false; \
|
||||
} \
|
||||
__expires_hardirq; \
|
||||
})
|
||||
|
||||
# define lockdep_hrtimer_exit(__hrtimer) \
|
||||
do { \
|
||||
if (!__hrtimer->is_hard) \
|
||||
# define lockdep_hrtimer_exit(__expires_hardirq) \
|
||||
do { \
|
||||
if (!__expires_hardirq) \
|
||||
current->irq_config = 0; \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
# define trace_hardirqs_on() do { } while (0)
|
||||
@ -72,8 +77,8 @@ do { \
|
||||
# define lockdep_softirq_enter() do { } while (0)
|
||||
# define lockdep_softirq_exit() do { } while (0)
|
||||
# define INIT_TRACE_IRQFLAGS
|
||||
# define lockdep_hrtimer_enter(__hrtimer) do { } while (0)
|
||||
# define lockdep_hrtimer_exit(__hrtimer) do { } while (0)
|
||||
# define lockdep_hrtimer_enter(__hrtimer) false
|
||||
# define lockdep_hrtimer_exit(__context) do { } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IRQSOFF_TRACER) || \
|
||||
|
@ -1498,6 +1498,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
|
||||
unsigned long flags) __must_hold(&cpu_base->lock)
|
||||
{
|
||||
enum hrtimer_restart (*fn)(struct hrtimer *);
|
||||
bool expires_in_hardirq;
|
||||
int restart;
|
||||
|
||||
lockdep_assert_held(&cpu_base->lock);
|
||||
@ -1532,11 +1533,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
|
||||
*/
|
||||
raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
|
||||
trace_hrtimer_expire_entry(timer, now);
|
||||
lockdep_hrtimer_enter(timer);
|
||||
expires_in_hardirq = lockdep_hrtimer_enter(timer);
|
||||
|
||||
restart = fn(timer);
|
||||
|
||||
lockdep_hrtimer_exit(timer);
|
||||
lockdep_hrtimer_exit(expires_in_hardirq);
|
||||
trace_hrtimer_expire_exit(timer);
|
||||
raw_spin_lock_irq(&cpu_base->lock);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user