diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-05-14 20:39:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-05-21 13:11:07 -0400 |
commit | 359566faefa850504d146839d74496f0cf12d3b9 (patch) | |
tree | 2000268b17f7fa236643c9d572147d883ace81ed | |
parent | ce72a16fa705f960ca2352e95a7c5f4801475e75 (diff) |
kernel_wait4()/kernel_waitid(): delay copying status to userland
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | kernel/exit.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index d44f12948c5f..94cdccf8e7e7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1002,7 +1002,7 @@ struct wait_opts { | |||
1002 | struct pid *wo_pid; | 1002 | struct pid *wo_pid; |
1003 | 1003 | ||
1004 | struct siginfo __user *wo_info; | 1004 | struct siginfo __user *wo_info; |
1005 | int __user *wo_stat; | 1005 | int wo_stat; |
1006 | struct rusage *wo_rusage; | 1006 | struct rusage *wo_rusage; |
1007 | 1007 | ||
1008 | wait_queue_t child_wait; | 1008 | wait_queue_t child_wait; |
@@ -1189,8 +1189,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1189 | retval = 0; | 1189 | retval = 0; |
1190 | status = (p->signal->flags & SIGNAL_GROUP_EXIT) | 1190 | status = (p->signal->flags & SIGNAL_GROUP_EXIT) |
1191 | ? p->signal->group_exit_code : p->exit_code; | 1191 | ? p->signal->group_exit_code : p->exit_code; |
1192 | if (!retval && wo->wo_stat) | 1192 | wo->wo_stat = status; |
1193 | retval = put_user(status, wo->wo_stat); | ||
1194 | 1193 | ||
1195 | infop = wo->wo_info; | 1194 | infop = wo->wo_info; |
1196 | if (!retval && infop) | 1195 | if (!retval && infop) |
@@ -1322,8 +1321,7 @@ unlock_sig: | |||
1322 | if (wo->wo_rusage) | 1321 | if (wo->wo_rusage) |
1323 | getrusage(p, RUSAGE_BOTH, wo->wo_rusage); | 1322 | getrusage(p, RUSAGE_BOTH, wo->wo_rusage); |
1324 | retval = 0; | 1323 | retval = 0; |
1325 | if (!retval && wo->wo_stat) | 1324 | wo->wo_stat = (exit_code << 8) | 0x7f; |
1326 | retval = put_user((exit_code << 8) | 0x7f, wo->wo_stat); | ||
1327 | 1325 | ||
1328 | infop = wo->wo_info; | 1326 | infop = wo->wo_info; |
1329 | if (!retval && infop) | 1327 | if (!retval && infop) |
@@ -1383,12 +1381,9 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) | |||
1383 | if (!wo->wo_info) { | 1381 | if (!wo->wo_info) { |
1384 | if (wo->wo_rusage) | 1382 | if (wo->wo_rusage) |
1385 | getrusage(p, RUSAGE_BOTH, wo->wo_rusage); | 1383 | getrusage(p, RUSAGE_BOTH, wo->wo_rusage); |
1386 | retval = 0; | ||
1387 | put_task_struct(p); | 1384 | put_task_struct(p); |
1388 | if (!retval && wo->wo_stat) | 1385 | wo->wo_stat = 0xffff; |
1389 | retval = put_user(0xffff, wo->wo_stat); | 1386 | retval = pid; |
1390 | if (!retval) | ||
1391 | retval = pid; | ||
1392 | } else { | 1387 | } else { |
1393 | retval = wait_noreap_copyout(wo, p, pid, uid, | 1388 | retval = wait_noreap_copyout(wo, p, pid, uid, |
1394 | CLD_CONTINUED, SIGCONT); | 1389 | CLD_CONTINUED, SIGCONT); |
@@ -1662,7 +1657,6 @@ static long kernel_waitid(int which, pid_t upid, struct siginfo __user *infop, | |||
1662 | wo.wo_pid = pid; | 1657 | wo.wo_pid = pid; |
1663 | wo.wo_flags = options; | 1658 | wo.wo_flags = options; |
1664 | wo.wo_info = infop; | 1659 | wo.wo_info = infop; |
1665 | wo.wo_stat = NULL; | ||
1666 | wo.wo_rusage = ru; | 1660 | wo.wo_rusage = ru; |
1667 | ret = do_wait(&wo); | 1661 | ret = do_wait(&wo); |
1668 | 1662 | ||
@@ -1734,10 +1728,12 @@ static long kernel_wait4(pid_t upid, int __user *stat_addr, | |||
1734 | wo.wo_pid = pid; | 1728 | wo.wo_pid = pid; |
1735 | wo.wo_flags = options | WEXITED; | 1729 | wo.wo_flags = options | WEXITED; |
1736 | wo.wo_info = NULL; | 1730 | wo.wo_info = NULL; |
1737 | wo.wo_stat = stat_addr; | 1731 | wo.wo_stat = 0; |
1738 | wo.wo_rusage = ru; | 1732 | wo.wo_rusage = ru; |
1739 | ret = do_wait(&wo); | 1733 | ret = do_wait(&wo); |
1740 | put_pid(pid); | 1734 | put_pid(pid); |
1735 | if (ret > 0 && stat_addr && put_user(wo.wo_stat, stat_addr)) | ||
1736 | ret = -EFAULT; | ||
1741 | 1737 | ||
1742 | return ret; | 1738 | return ret; |
1743 | } | 1739 | } |