diff options
author | Vitaly Mayatskikh <v.mayatskih@gmail.com> | 2009-09-23 18:56:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 10:21:00 -0400 |
commit | b6fe2d117e98805ee76352e6468f87d494a97292 (patch) | |
tree | 3de99eb7652647000b53bca1f6ea740c926ccfca | |
parent | dfe16dfa4ac178d9a10b489a73d535c6976e48d2 (diff) |
wait_noreap_copyout(): check for ->wo_info != NULL
Current behaviour of sys_waitid() looks odd. If user passes infop ==
NULL, sys_waitid() returns success. When user additionally specifies flag
WNOWAIT, sys_waitid() returns -EFAULT on the same conditions. When user
combines WNOWAIT with WCONTINUED, sys_waitid() again returns success.
This patch adds check for ->wo_info in wait_noreap_copyout().
User-visible change: starting from this commit, sys_waitid() always checks
infop != NULL and does not fail if it is NULL.
Signed-off-by: Vitaly Mayatskikh <v.mayatskih@gmail.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/exit.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 2cc69eb8db2a..6c75ff83a8fe 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1140,18 +1140,20 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p, | |||
1140 | 1140 | ||
1141 | put_task_struct(p); | 1141 | put_task_struct(p); |
1142 | infop = wo->wo_info; | 1142 | infop = wo->wo_info; |
1143 | if (!retval) | 1143 | if (infop) { |
1144 | retval = put_user(SIGCHLD, &infop->si_signo); | 1144 | if (!retval) |
1145 | if (!retval) | 1145 | retval = put_user(SIGCHLD, &infop->si_signo); |
1146 | retval = put_user(0, &infop->si_errno); | 1146 | if (!retval) |
1147 | if (!retval) | 1147 | retval = put_user(0, &infop->si_errno); |
1148 | retval = put_user((short)why, &infop->si_code); | 1148 | if (!retval) |
1149 | if (!retval) | 1149 | retval = put_user((short)why, &infop->si_code); |
1150 | retval = put_user(pid, &infop->si_pid); | 1150 | if (!retval) |
1151 | if (!retval) | 1151 | retval = put_user(pid, &infop->si_pid); |
1152 | retval = put_user(uid, &infop->si_uid); | 1152 | if (!retval) |
1153 | if (!retval) | 1153 | retval = put_user(uid, &infop->si_uid); |
1154 | retval = put_user(status, &infop->si_status); | 1154 | if (!retval) |
1155 | retval = put_user(status, &infop->si_status); | ||
1156 | } | ||
1155 | if (!retval) | 1157 | if (!retval) |
1156 | retval = pid; | 1158 | retval = pid; |
1157 | return retval; | 1159 | return retval; |