[PATCH] print_worker_info: Handle pointer with more care

From: Richard Weinberger
Date: Fri Aug 16 2013 - 11:57:33 EST


The function has a nice comment:
/*
* This function is called without any synchronization and @task
* could be in any state. Be careful with dereferences.
*/

But a few lines later it blindly dereferences a few pointers.
E.g. It can happen that the worker function is already done,
then worker->current_pwq is NULL.

Signed-off-by: Richard Weinberger <richard@xxxxxx>
---
kernel/workqueue.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7f5d4be..61382b9 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4465,6 +4465,8 @@ void print_worker_info(const char *log_lvl, struct task_struct *task)
* could be in any state. Be careful with dereferences.
*/
worker = probe_kthread_data(task);
+ if (!worker)
+ return;

/*
* Carefully copy the associated workqueue's workfn and name. Keep
@@ -4472,7 +4474,13 @@ void print_worker_info(const char *log_lvl, struct task_struct *task)
*/
probe_kernel_read(&fn, &worker->current_func, sizeof(fn));
probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq));
+ if (!pwq)
+ goto print;
+
probe_kernel_read(&wq, &pwq->wq, sizeof(wq));
+ if (!wq)
+ goto print;
+
probe_kernel_read(name, wq->name, sizeof(name) - 1);

/* copy worker description */
@@ -4480,6 +4488,7 @@ void print_worker_info(const char *log_lvl, struct task_struct *task)
if (desc_valid)
probe_kernel_read(desc, worker->desc, sizeof(desc) - 1);

+print:
if (fn || name[0] || desc[0]) {
printk("%sWorkqueue: %s %pf", log_lvl, name, fn);
if (desc[0])
--
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/