Make sure the timer belonging to the delayed work in the LinuxKPI
gets drained before invoking the work function. Else the timer mutex may still be in use which can lead to use-after-free situations, because the work function might free the work structure before returning. MFC after: 1 week Sponsored by: Mellanox Technologies
This commit is contained in:
parent
9eddd5d91f
commit
3a9dfc3d72
@ -215,6 +215,7 @@ extern struct workqueue_struct *system_power_efficient_wq;
|
||||
|
||||
extern void linux_init_delayed_work(struct delayed_work *, work_func_t);
|
||||
extern void linux_work_fn(void *, int);
|
||||
extern void linux_delayed_work_fn(void *, int);
|
||||
extern struct workqueue_struct *linux_create_workqueue_common(const char *, int);
|
||||
extern void linux_destroy_workqueue(struct workqueue_struct *);
|
||||
extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *);
|
||||
|
@ -260,6 +260,23 @@ linux_work_fn(void *context, int pending)
|
||||
WQ_EXEC_UNLOCK(wq);
|
||||
}
|
||||
|
||||
void
|
||||
linux_delayed_work_fn(void *context, int pending)
|
||||
{
|
||||
struct delayed_work *dwork = context;
|
||||
|
||||
/*
|
||||
* Make sure the timer belonging to the delayed work gets
|
||||
* drained before invoking the work function. Else the timer
|
||||
* mutex may still be in use which can lead to use-after-free
|
||||
* situations, because the work function might free the work
|
||||
* structure before returning.
|
||||
*/
|
||||
callout_drain(&dwork->timer.callout);
|
||||
|
||||
linux_work_fn(&dwork->work, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_delayed_work_timer_fn(void *arg)
|
||||
{
|
||||
@ -550,7 +567,8 @@ void
|
||||
linux_init_delayed_work(struct delayed_work *dwork, work_func_t func)
|
||||
{
|
||||
memset(dwork, 0, sizeof(*dwork));
|
||||
INIT_WORK(&dwork->work, func);
|
||||
dwork->work.func = func;
|
||||
TASK_INIT(&dwork->work.work_task, 0, linux_delayed_work_fn, dwork);
|
||||
mtx_init(&dwork->timer.mtx, spin_lock_name("lkpi-dwork"), NULL,
|
||||
MTX_DEF | MTX_NOWITNESS);
|
||||
callout_init_mtx(&dwork->timer.callout, &dwork->timer.mtx, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user