aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-03-30 21:41:25 -0400
committerRoland McGrath <roland@redhat.com>2008-07-16 21:02:34 -0400
commit14dd0b81414a58caf0296dbeace016bb0a5d11ab (patch)
treecbb81c1f73b13c41645ff01019d303e48a5ca7af
parentf470021adb9190819c03d6d8c5c860a17480aa6d (diff)
do_wait: return security_task_wait() error code in place of -ECHILD
This reverts the effect of commit f2cc3eb133baa2e9dc8efd40f417106b2ee520f3 "do_wait: fix security checks". That change reverted the effect of commit 73243284463a761e04d69d22c7516b2be7de096c. The rationale for the original commit still stands. The inconsistent treatment of children hidden by ptrace was an unintended omission in the original change and in no way invalidates its purpose. This makes do_wait return the error returned by security_task_wait() (usually -EACCES) in place of -ECHILD when there are some children the caller would be able to wait for if not for the permission failure. A permission error will give the user a clue to look for security policy problems, rather than for mysterious wait bugs. Signed-off-by: Roland McGrath <roland@redhat.com>
-rw-r--r--kernel/exit.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 1e909826a804..a2af6cac823c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1199,14 +1199,10 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options,
1199 return 0; 1199 return 0;
1200 1200
1201 err = security_task_wait(p); 1201 err = security_task_wait(p);
1202 if (likely(!err)) 1202 if (err)
1203 return 1; 1203 return err;
1204 1204
1205 if (type != PIDTYPE_PID) 1205 return 1;
1206 return 0;
1207 /* This child was explicitly requested, abort */
1208 read_unlock(&tasklist_lock);
1209 return err;
1210} 1206}
1211 1207
1212static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid, 1208static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid,
@@ -1536,7 +1532,8 @@ static int wait_task_continued(struct task_struct *p, int options,
1536 * -ECHILD should be in *@notask_error before the first call. 1532 * -ECHILD should be in *@notask_error before the first call.
1537 * Returns nonzero for a final return, when we have unlocked tasklist_lock. 1533 * Returns nonzero for a final return, when we have unlocked tasklist_lock.
1538 * Returns zero if the search for a child should continue; 1534 * Returns zero if the search for a child should continue;
1539 * then *@notask_error is 0 if @p is an eligible child, or still -ECHILD. 1535 * then *@notask_error is 0 if @p is an eligible child,
1536 * or another error from security_task_wait(), or still -ECHILD.
1540 */ 1537 */
1541static int wait_consider_task(struct task_struct *parent, int ptrace, 1538static int wait_consider_task(struct task_struct *parent, int ptrace,
1542 struct task_struct *p, int *notask_error, 1539 struct task_struct *p, int *notask_error,
@@ -1545,9 +1542,21 @@ static int wait_consider_task(struct task_struct *parent, int ptrace,
1545 int __user *stat_addr, struct rusage __user *ru) 1542 int __user *stat_addr, struct rusage __user *ru)
1546{ 1543{
1547 int ret = eligible_child(type, pid, options, p); 1544 int ret = eligible_child(type, pid, options, p);
1548 if (ret <= 0) 1545 if (!ret)
1549 return ret; 1546 return ret;
1550 1547
1548 if (unlikely(ret < 0)) {
1549 /*
1550 * If we have not yet seen any eligible child,
1551 * then let this error code replace -ECHILD.
1552 * A permission error will give the user a clue
1553 * to look for security policy problems, rather
1554 * than for mysterious wait bugs.
1555 */
1556 if (*notask_error)
1557 *notask_error = ret;
1558 }
1559
1551 if (likely(!ptrace) && unlikely(p->ptrace)) { 1560 if (likely(!ptrace) && unlikely(p->ptrace)) {
1552 /* 1561 /*
1553 * This child is hidden by ptrace. 1562 * This child is hidden by ptrace.
@@ -1585,7 +1594,8 @@ static int wait_consider_task(struct task_struct *parent, int ptrace,
1585 * -ECHILD should be in *@notask_error before the first call. 1594 * -ECHILD should be in *@notask_error before the first call.
1586 * Returns nonzero for a final return, when we have unlocked tasklist_lock. 1595 * Returns nonzero for a final return, when we have unlocked tasklist_lock.
1587 * Returns zero if the search for a child should continue; then 1596 * Returns zero if the search for a child should continue; then
1588 * *@notask_error is 0 if there were any eligible children, or still -ECHILD. 1597 * *@notask_error is 0 if there were any eligible children,
1598 * or another error from security_task_wait(), or still -ECHILD.
1589 */ 1599 */
1590static int do_wait_thread(struct task_struct *tsk, int *notask_error, 1600static int do_wait_thread(struct task_struct *tsk, int *notask_error,
1591 enum pid_type type, struct pid *pid, int options, 1601 enum pid_type type, struct pid *pid, int options,