* [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid()
@ 2013-10-07 10:29 Chen Gang
2013-10-07 12:43 ` Oleg Nesterov
0 siblings, 1 reply; 5+ messages in thread
From: Chen Gang @ 2013-10-07 10:29 UTC (permalink / raw)
To: Eric W. Biederman, Serge Hallyn, Oleg Nesterov, Serge E. Hallyn
Cc: Andrew Morton, linux-kernel@vger.kernel.org
Within __change_pid(), 'new' may be NULL if it comes from detach_pid(),
and 'link->pid' also may be NULL ("link->pid = new"), so theoretically,\
the original 'link->pid' may be NULL, too.
In real world, at least now, all callers which will call detach_pid()
or change_pid() will not cause issue, but still recommend to check it
in __change_pid() to let itself consistency.
After the modification, it passed a simpe test: "build -> boot up ->
[s/g]et_[p/s/g]id() test by LTP tools".
Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
kernel/pid.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/kernel/pid.c b/kernel/pid.c
index 9b9a266..15b1b3d 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -399,6 +399,9 @@ static void __change_pid(struct task_struct *task, enum pid_type type,
hlist_del_rcu(&link->node);
link->pid = new;
+ if (!pid)
+ return;
+
for (tmp = PIDTYPE_MAX; --tmp >= 0; )
if (!hlist_empty(&pid->tasks[tmp]))
return;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() 2013-10-07 10:29 [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() Chen Gang @ 2013-10-07 12:43 ` Oleg Nesterov 2013-10-07 21:53 ` Chen Gang 0 siblings, 1 reply; 5+ messages in thread From: Oleg Nesterov @ 2013-10-07 12:43 UTC (permalink / raw) To: Chen Gang Cc: Eric W. Biederman, Serge Hallyn, Serge E. Hallyn, Andrew Morton, linux-kernel@vger.kernel.org On 10/07, Chen Gang wrote: > > Within __change_pid(), 'new' may be NULL if it comes from detach_pid(), > and 'link->pid' also may be NULL ("link->pid = new"), so theoretically,\ > the original 'link->pid' may be NULL, too. I don't really understand this "theoretically", > In real world, at least now, all callers which will call detach_pid() > or change_pid() will not cause issue, Yes, > but still recommend to check it > in __change_pid() to let itself consistency. Why? Contrary, I think we should not hide the problem. If __change_pid() is called when task->pids[type].pid is already NULL there is something seriously wrong. Oleg. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() 2013-10-07 12:43 ` Oleg Nesterov @ 2013-10-07 21:53 ` Chen Gang 2013-10-08 17:56 ` Oleg Nesterov 0 siblings, 1 reply; 5+ messages in thread From: Chen Gang @ 2013-10-07 21:53 UTC (permalink / raw) To: Oleg Nesterov Cc: Eric W. Biederman, Serge Hallyn, Serge E. Hallyn, Andrew Morton, linux-kernel@vger.kernel.org On 10/07/2013 08:43 PM, Oleg Nesterov wrote: > On 10/07, Chen Gang wrote: >> >> Within __change_pid(), 'new' may be NULL if it comes from detach_pid(), >> and 'link->pid' also may be NULL ("link->pid = new"), so theoretically,\ >> the original 'link->pid' may be NULL, too. > > I don't really understand this "theoretically", > >> In real world, at least now, all callers which will call detach_pid() >> or change_pid() will not cause issue, > > Yes, > >> but still recommend to check it >> in __change_pid() to let itself consistency. > > Why? > > Contrary, I think we should not hide the problem. If __change_pid() is > called when task->pids[type].pid is already NULL there is something > seriously wrong. > Hmm... In my opinion, it means need BUG_ON() for original 'link->pid'. --------------------------------patch begin----------------------------- [PATCH] kernel/pid.c: add BUG_ON() for "!pid" in __change_pid() Within __change_pid(), 'new' may be NULL if it comes from detach_pid(), and 'link->pid' also may be NULL ("link->pid = new"), so theoretically, the original 'link->pid' may be NULL, too. But in real world, all related extern functions always assume "if 'link->pid' is already NULL, there must be something seriously wrong", although __change_pid() can accept parameter 'new' as NULL. So in __change_pid(), need add BUG_ON() for it: "it should not happen, when it really happen, OS must be continuing blindly, and next will cause serious issue". Signed-off-by: Chen Gang <gang.chen@asianux.com> --- kernel/pid.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/kernel/pid.c b/kernel/pid.c index 9b9a266..8fc87f1 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -396,6 +396,12 @@ static void __change_pid(struct task_struct *task, enum pid_type type, link = &task->pids[type]; pid = link->pid; + /* + * If task->pids[type].pid is already NULL, there must be something + * seriously wrong + */ + BUG_ON(!pid); + hlist_del_rcu(&link->node); link->pid = new; -- 1.7.7.6 --------------------------------patch end------------------------------- > Oleg. > > > -- Chen Gang ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() 2013-10-07 21:53 ` Chen Gang @ 2013-10-08 17:56 ` Oleg Nesterov 2013-10-09 1:03 ` Chen Gang 0 siblings, 1 reply; 5+ messages in thread From: Oleg Nesterov @ 2013-10-08 17:56 UTC (permalink / raw) To: Chen Gang Cc: Eric W. Biederman, Serge Hallyn, Serge E. Hallyn, Andrew Morton, linux-kernel@vger.kernel.org On 10/08, Chen Gang wrote: > > On 10/07/2013 08:43 PM, Oleg Nesterov wrote: > > > >> but still recommend to check it > >> in __change_pid() to let itself consistency. > > > > Why? > > > > Contrary, I think we should not hide the problem. If __change_pid() is > > called when task->pids[type].pid is already NULL there is something > > seriously wrong. > > > > Hmm... In my opinion, it means need BUG_ON() for original 'link->pid'. > > --------------------------------patch begin----------------------------- > > [PATCH] kernel/pid.c: add BUG_ON() for "!pid" in __change_pid() > > Within __change_pid(), 'new' may be NULL if it comes from detach_pid(), Yes, this is fine, > and 'link->pid' also may be NULL ("link->pid = new"), > ... > the original 'link->pid' may be NULL, too. Too? You mean, it becomes NULL after detach_pid(). > But in real world, all related extern functions always assume "if > 'link->pid' is already NULL, there must be something seriously wrong", > although __change_pid() can accept parameter 'new' as NULL. I simply can't understand why you mix "new == NULL" and "link->pid == NULL". > So in __change_pid(), need add BUG_ON() for it: "it should not happen, > when it really happen, OS must be continuing blindly, OS will crash a couple of lines below trying to dereference this pointer. > --- a/kernel/pid.c > +++ b/kernel/pid.c > @@ -396,6 +396,12 @@ static void __change_pid(struct task_struct *task, enum pid_type type, > link = &task->pids[type]; > pid = link->pid; > > + /* > + * If task->pids[type].pid is already NULL, there must be something > + * seriously wrong > + */ > + BUG_ON(!pid); Following this logic you should also add BUG_ON(!task); BUG_ON(!link->node.next); BUG_ON(!link->node.prev || link->node.prev == LIST_POISON2); ... Seriously, I do not understand the point. Yes, detach_pid() should not be called twice. And it has a single caller. And this caller will crash too if it is called twice. So you can also add BUG_ON() into __unhash_process(). And so on. Oleg. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() 2013-10-08 17:56 ` Oleg Nesterov @ 2013-10-09 1:03 ` Chen Gang 0 siblings, 0 replies; 5+ messages in thread From: Chen Gang @ 2013-10-09 1:03 UTC (permalink / raw) To: Oleg Nesterov Cc: Eric W. Biederman, Serge Hallyn, Serge E. Hallyn, Andrew Morton, linux-kernel@vger.kernel.org On 10/09/2013 01:56 AM, Oleg Nesterov wrote: > On 10/08, Chen Gang wrote: >> >> On 10/07/2013 08:43 PM, Oleg Nesterov wrote: >>> >>>> but still recommend to check it >>>> in __change_pid() to let itself consistency. >>> >>> Why? >>> >>> Contrary, I think we should not hide the problem. If __change_pid() is >>> called when task->pids[type].pid is already NULL there is something >>> seriously wrong. >>> >> >> Hmm... In my opinion, it means need BUG_ON() for original 'link->pid'. >> >> --------------------------------patch begin----------------------------- >> >> [PATCH] kernel/pid.c: add BUG_ON() for "!pid" in __change_pid() >> >> Within __change_pid(), 'new' may be NULL if it comes from detach_pid(), > > Yes, this is fine, > >> and 'link->pid' also may be NULL ("link->pid = new"), >> ... >> the original 'link->pid' may be NULL, too. > > Too? You mean, it becomes NULL after detach_pid(). > >> But in real world, all related extern functions always assume "if >> 'link->pid' is already NULL, there must be something seriously wrong", >> although __change_pid() can accept parameter 'new' as NULL. > > I simply can't understand why you mix "new == NULL" and "link->pid == NULL". > >> So in __change_pid(), need add BUG_ON() for it: "it should not happen, >> when it really happen, OS must be continuing blindly, > > OS will crash a couple of lines below trying to dereference this pointer. > >> --- a/kernel/pid.c >> +++ b/kernel/pid.c >> @@ -396,6 +396,12 @@ static void __change_pid(struct task_struct *task, enum pid_type type, >> link = &task->pids[type]; >> pid = link->pid; >> >> + /* >> + * If task->pids[type].pid is already NULL, there must be something >> + * seriously wrong >> + */ >> + BUG_ON(!pid); > > Following this logic you should also add > > BUG_ON(!task); > BUG_ON(!link->node.next); > BUG_ON(!link->node.prev || link->node.prev == LIST_POISON2); > ... > > Seriously, I do not understand the point. Yes, detach_pid() should not > be called twice. And it has a single caller. And this caller will crash > too if it is called twice. So you can also add BUG_ON() into > __unhash_process(). And so on. > In my opinion, for using BUG_ON(), it has 3 requirements: - OS is just continuing blindly. - next, will cause real issue (or need use WARN_ON instead of). - Can let the related code self consitency (or will add many wastes). Your demo are match 2 requrements, but not match the 3rd one: "it is reasonable to assume 'task', 'link', and 'link->node' are valid in __change_pid()". But for link->pid, the function name '__change_pid' tells us it is only for changing pid, if 'new' can be NULL, 'link->pid' also can be NULL, so the original 'link-pid' can be NULL, too. So for self consistency, we also can change the function name from '__change_pid' to another one (e.g. 'change_orig_valid_pid'), to let itself consistency (so don't need BUG_ON) The related patch is below, please check, thanks. --------------------------------patch begin----------------------------- kernel/pid.c: use 'change_orig_valid_pid' instead of '__change_pid' for function name For function name '__change_pid' is only for changing pid. In fact, it always assumes the original pid is valid, but new pid can be NULL, so recommend to use 'change_orig_valid_pid' instead of. Signed-off-by: Chen Gang <gang.chen@asianux.com> --- kernel/pid.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/pid.c b/kernel/pid.c index 9b9a266..408a3b5 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -386,7 +386,7 @@ void attach_pid(struct task_struct *task, enum pid_type type) hlist_add_head_rcu(&link->node, &link->pid->tasks[type]); } -static void __change_pid(struct task_struct *task, enum pid_type type, +static void change_orig_valid_pid(struct task_struct *task, enum pid_type type, struct pid *new) { struct pid_link *link; @@ -408,13 +408,13 @@ static void __change_pid(struct task_struct *task, enum pid_type type, void detach_pid(struct task_struct *task, enum pid_type type) { - __change_pid(task, type, NULL); + change_orig_valid_pid(task, type, NULL); } void change_pid(struct task_struct *task, enum pid_type type, struct pid *pid) { - __change_pid(task, type, pid); + change_orig_valid_pid(task, type, pid); attach_pid(task, type); } -- 1.7.7.6 --------------------------------patch end------------------------------- Thanks. -- Chen Gang ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-10-09 1:04 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-10-07 10:29 [PATCH] kernel/pid.c: check pid whether be NULL in __change_pid() Chen Gang 2013-10-07 12:43 ` Oleg Nesterov 2013-10-07 21:53 ` Chen Gang 2013-10-08 17:56 ` Oleg Nesterov 2013-10-09 1:03 ` Chen Gang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).