All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] print_worker_info: Handle pointer with more care
@ 2013-08-16 15:56 Richard Weinberger
  2013-08-16 16:12 ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2013-08-16 15:56 UTC (permalink / raw)
  To: tj; +Cc: linux-kernel, Richard Weinberger

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@nod.at>
---
 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


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 15:56 [PATCH] print_worker_info: Handle pointer with more care Richard Weinberger
@ 2013-08-16 16:12 ` Tejun Heo
  2013-08-16 16:15   ` Richard Weinberger
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2013-08-16 16:12 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: linux-kernel

On Fri, Aug 16, 2013 at 05:56:46PM +0200, Richard Weinberger wrote:
> 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.
...
>  	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;
> +

But none of the above are dereferences.  &ptr->field is offset
calculation, not a dereference.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:12 ` Tejun Heo
@ 2013-08-16 16:15   ` Richard Weinberger
  2013-08-16 16:28     ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2013-08-16 16:15 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel

Am 16.08.2013 18:12, schrieb Tejun Heo:
> On Fri, Aug 16, 2013 at 05:56:46PM +0200, Richard Weinberger wrote:
>> 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.
> ...
>>  	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;
>> +
> 
> But none of the above are dereferences.  &ptr->field is offset
> calculation, not a dereference.

On UML I hit the case that pwq is NULL.
Then we oops at &pwq->wq...

Thanks,
//richard


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:15   ` Richard Weinberger
@ 2013-08-16 16:28     ` Tejun Heo
  2013-08-16 16:38       ` Richard Weinberger
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2013-08-16 16:28 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: linux-kernel, Jeff Dike, Richard Weinberger, user-mode-linux-devel

On Fri, Aug 16, 2013 at 06:15:07PM +0200, Richard Weinberger wrote:
> On UML I hit the case that pwq is NULL.
> Then we oops at &pwq->wq...

Hmmm?  I'm confused.  &pwq->wq is pwq's pointer + wq's offset in pwq.
It doesn't involve dereferencing pwq->wq.  Maybe uml isn't
implementing probe_kernel_thread()?  Now that I think about it, I'm
not sure how it could.

cc'ing uml people.  Hey, guys, workqueue uses proble_kernel_read() to
print out workqueue related information during oops because those
events are completely asynchronous and workqueue states may not be
consistently accessible.  It seems like uml doesn't implement
probe_kernel_read() and tries direct derference of incorrect pointers
leading to its own oops.  Maybe uml should check whether the memory is
mapped from probe_kernel_read()?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:28     ` Tejun Heo
@ 2013-08-16 16:38       ` Richard Weinberger
  2013-08-16 16:45         ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2013-08-16 16:38 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, Jeff Dike, user-mode-linux-devel

Am 16.08.2013 18:28, schrieb Tejun Heo:
> On Fri, Aug 16, 2013 at 06:15:07PM +0200, Richard Weinberger wrote:
>> On UML I hit the case that pwq is NULL.
>> Then we oops at &pwq->wq...
> 
> Hmmm?  I'm confused.  &pwq->wq is pwq's pointer + wq's offset in pwq.
> It doesn't involve dereferencing pwq->wq.  Maybe uml isn't
> implementing probe_kernel_thread()?  Now that I think about it, I'm
> not sure how it could.
> 
> cc'ing uml people.  Hey, guys, workqueue uses proble_kernel_read() to
> print out workqueue related information during oops because those
> events are completely asynchronous and workqueue states may not be
> consistently accessible.  It seems like uml doesn't implement
> probe_kernel_read() and tries direct derference of incorrect pointers
> leading to its own oops.  Maybe uml should check whether the memory is
> mapped from probe_kernel_read()?

You are already talking to UML people. ;)
Anyway, I'll investigate into that.
What I see so far is that pwq is NULL after probe_kernel_read().

Thanks,
//richard

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:38       ` Richard Weinberger
@ 2013-08-16 16:45         ` Tejun Heo
  2013-08-16 16:53           ` Richard Weinberger
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2013-08-16 16:45 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: linux-kernel, Jeff Dike, user-mode-linux-devel

Hello,

On Fri, Aug 16, 2013 at 06:38:58PM +0200, Richard Weinberger wrote:
> > cc'ing uml people.  Hey, guys, workqueue uses proble_kernel_read() to
> > print out workqueue related information during oops because those
> > events are completely asynchronous and workqueue states may not be
> > consistently accessible.  It seems like uml doesn't implement
> > probe_kernel_read() and tries direct derference of incorrect pointers
> > leading to its own oops.  Maybe uml should check whether the memory is
> > mapped from probe_kernel_read()?
> 
> You are already talking to UML people. ;)

Ooh... :)

> Anyway, I'll investigate into that.
> What I see so far is that pwq is NULL after probe_kernel_read().

Yeah, and that should be fine.  &pwq->wq would be just an offset of wq
from NULL which is an invalid pointer but probe_kernel_read() should
be able to handle that and probably just return 0 or -1 (all bits
set).  I *think* what's necessary is making probe_kernel_read() use
mincore() to fine out whether the requested address is mapped (it
should return -EFAULT if not) and try to dereference the address iff
it's mapped.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:45         ` Tejun Heo
@ 2013-08-16 16:53           ` Richard Weinberger
  2013-08-16 17:20             ` Richard Weinberger
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2013-08-16 16:53 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, Jeff Dike, user-mode-linux-devel

Am 16.08.2013 18:45, schrieb Tejun Heo:
> Hello,
> 
> On Fri, Aug 16, 2013 at 06:38:58PM +0200, Richard Weinberger wrote:
>>> cc'ing uml people.  Hey, guys, workqueue uses proble_kernel_read() to
>>> print out workqueue related information during oops because those
>>> events are completely asynchronous and workqueue states may not be
>>> consistently accessible.  It seems like uml doesn't implement
>>> probe_kernel_read() and tries direct derference of incorrect pointers
>>> leading to its own oops.  Maybe uml should check whether the memory is
>>> mapped from probe_kernel_read()?
>>
>> You are already talking to UML people. ;)
> 
> Ooh... :)
> 
>> Anyway, I'll investigate into that.
>> What I see so far is that pwq is NULL after probe_kernel_read().
> 
> Yeah, and that should be fine.  &pwq->wq would be just an offset of wq

Yep. Now my brain also parsed the C notation correctly.
Sorry for the completely wrong patch.

> from NULL which is an invalid pointer but probe_kernel_read() should
> be able to handle that and probably just return 0 or -1 (all bits
> set).  I *think* what's necessary is making probe_kernel_read() use
> mincore() to fine out whether the requested address is mapped (it
> should return -EFAULT if not) and try to dereference the address iff
> it's mapped.

UML needs a custom probe_kernel_read()? Fine. :)

Thanks,
//richard


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] print_worker_info: Handle pointer with more care
  2013-08-16 16:53           ` Richard Weinberger
@ 2013-08-16 17:20             ` Richard Weinberger
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Weinberger @ 2013-08-16 17:20 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, Jeff Dike, user-mode-linux-devel

Am 16.08.2013 18:53, schrieb Richard Weinberger:
>> Yeah, and that should be fine.  &pwq->wq would be just an offset of wq
> 
> Yep. Now my brain also parsed the C notation correctly.
> Sorry for the completely wrong patch.
> 
>> from NULL which is an invalid pointer but probe_kernel_read() should
>> be able to handle that and probably just return 0 or -1 (all bits
>> set).  I *think* what's necessary is making probe_kernel_read() use
>> mincore() to fine out whether the requested address is mapped (it
>> should return -EFAULT if not) and try to dereference the address iff
>> it's mapped.
> 
> UML needs a custom probe_kernel_read()? Fine. :)

With my own probe_kernel_read() that uses mincore()
it works fine so far. :-)

Thanks,
//richard


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-08-16 17:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-16 15:56 [PATCH] print_worker_info: Handle pointer with more care Richard Weinberger
2013-08-16 16:12 ` Tejun Heo
2013-08-16 16:15   ` Richard Weinberger
2013-08-16 16:28     ` Tejun Heo
2013-08-16 16:38       ` Richard Weinberger
2013-08-16 16:45         ` Tejun Heo
2013-08-16 16:53           ` Richard Weinberger
2013-08-16 17:20             ` Richard Weinberger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.