Skip to content

Commit 359566f

Browse files
author
Al Viro
committed
kernel_wait4()/kernel_waitid(): delay copying status to userland
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent ce72a16 commit 359566f

File tree

1 file changed

+8
-12
lines changed

1 file changed

+8
-12
lines changed

kernel/exit.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ struct wait_opts {
10021002
struct pid *wo_pid;
10031003

10041004
struct siginfo __user *wo_info;
1005-
int __user *wo_stat;
1005+
int wo_stat;
10061006
struct rusage *wo_rusage;
10071007

10081008
wait_queue_t child_wait;
@@ -1189,8 +1189,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
11891189
retval = 0;
11901190
status = (p->signal->flags & SIGNAL_GROUP_EXIT)
11911191
? p->signal->group_exit_code : p->exit_code;
1192-
if (!retval && wo->wo_stat)
1193-
retval = put_user(status, wo->wo_stat);
1192+
wo->wo_stat = status;
11941193

11951194
infop = wo->wo_info;
11961195
if (!retval && infop)
@@ -1322,8 +1321,7 @@ static int wait_task_stopped(struct wait_opts *wo,
13221321
if (wo->wo_rusage)
13231322
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
13241323
retval = 0;
1325-
if (!retval && wo->wo_stat)
1326-
retval = put_user((exit_code << 8) | 0x7f, wo->wo_stat);
1324+
wo->wo_stat = (exit_code << 8) | 0x7f;
13271325

13281326
infop = wo->wo_info;
13291327
if (!retval && infop)
@@ -1383,12 +1381,9 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
13831381
if (!wo->wo_info) {
13841382
if (wo->wo_rusage)
13851383
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
1386-
retval = 0;
13871384
put_task_struct(p);
1388-
if (!retval && wo->wo_stat)
1389-
retval = put_user(0xffff, wo->wo_stat);
1390-
if (!retval)
1391-
retval = pid;
1385+
wo->wo_stat = 0xffff;
1386+
retval = pid;
13921387
} else {
13931388
retval = wait_noreap_copyout(wo, p, pid, uid,
13941389
CLD_CONTINUED, SIGCONT);
@@ -1662,7 +1657,6 @@ static long kernel_waitid(int which, pid_t upid, struct siginfo __user *infop,
16621657
wo.wo_pid = pid;
16631658
wo.wo_flags = options;
16641659
wo.wo_info = infop;
1665-
wo.wo_stat = NULL;
16661660
wo.wo_rusage = ru;
16671661
ret = do_wait(&wo);
16681662

@@ -1734,10 +1728,12 @@ static long kernel_wait4(pid_t upid, int __user *stat_addr,
17341728
wo.wo_pid = pid;
17351729
wo.wo_flags = options | WEXITED;
17361730
wo.wo_info = NULL;
1737-
wo.wo_stat = stat_addr;
1731+
wo.wo_stat = 0;
17381732
wo.wo_rusage = ru;
17391733
ret = do_wait(&wo);
17401734
put_pid(pid);
1735+
if (ret > 0 && stat_addr && put_user(wo.wo_stat, stat_addr))
1736+
ret = -EFAULT;
17411737

17421738
return ret;
17431739
}

0 commit comments

Comments
 (0)