diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 2d8be7ebb0f7..ccb87162ff62 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -46,12 +46,14 @@ | |||
| 46 | #include <linux/blkdev.h> | 46 | #include <linux/blkdev.h> |
| 47 | #include <linux/task_io_accounting_ops.h> | 47 | #include <linux/task_io_accounting_ops.h> |
| 48 | #include <linux/tracehook.h> | 48 | #include <linux/tracehook.h> |
| 49 | #include <linux/init_task.h> | ||
| 49 | #include <trace/sched.h> | 50 | #include <trace/sched.h> |
| 50 | 51 | ||
| 51 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
| 52 | #include <asm/unistd.h> | 53 | #include <asm/unistd.h> |
| 53 | #include <asm/pgtable.h> | 54 | #include <asm/pgtable.h> |
| 54 | #include <asm/mmu_context.h> | 55 | #include <asm/mmu_context.h> |
| 56 | #include "cred-internals.h" | ||
| 55 | 57 | ||
| 56 | static void exit_mm(struct task_struct * tsk); | 58 | static void exit_mm(struct task_struct * tsk); |
| 57 | 59 | ||
| @@ -164,7 +166,10 @@ void release_task(struct task_struct * p) | |||
| 164 | int zap_leader; | 166 | int zap_leader; |
| 165 | repeat: | 167 | repeat: |
| 166 | tracehook_prepare_release_task(p); | 168 | tracehook_prepare_release_task(p); |
| 167 | atomic_dec(&p->user->processes); | 169 | /* don't need to get the RCU readlock here - the process is dead and |
| 170 | * can't be modifying its own credentials */ | ||
| 171 | atomic_dec(&__task_cred(p)->user->processes); | ||
| 172 | |||
| 168 | proc_flush_task(p); | 173 | proc_flush_task(p); |
| 169 | write_lock_irq(&tasklist_lock); | 174 | write_lock_irq(&tasklist_lock); |
| 170 | tracehook_finish_release_task(p); | 175 | tracehook_finish_release_task(p); |
| @@ -339,12 +344,12 @@ static void reparent_to_kthreadd(void) | |||
| 339 | /* cpus_allowed? */ | 344 | /* cpus_allowed? */ |
| 340 | /* rt_priority? */ | 345 | /* rt_priority? */ |
| 341 | /* signals? */ | 346 | /* signals? */ |
| 342 | security_task_reparent_to_init(current); | ||
| 343 | memcpy(current->signal->rlim, init_task.signal->rlim, | 347 | memcpy(current->signal->rlim, init_task.signal->rlim, |
| 344 | sizeof(current->signal->rlim)); | 348 | sizeof(current->signal->rlim)); |
| 345 | atomic_inc(&(INIT_USER->__count)); | 349 | |
| 350 | atomic_inc(&init_cred.usage); | ||
| 351 | commit_creds(&init_cred); | ||
| 346 | write_unlock_irq(&tasklist_lock); | 352 | write_unlock_irq(&tasklist_lock); |
| 347 | switch_uid(INIT_USER); | ||
| 348 | } | 353 | } |
| 349 | 354 | ||
| 350 | void __set_special_pids(struct pid *pid) | 355 | void __set_special_pids(struct pid *pid) |
| @@ -1078,7 +1083,6 @@ NORET_TYPE void do_exit(long code) | |||
| 1078 | check_stack_usage(); | 1083 | check_stack_usage(); |
| 1079 | exit_thread(); | 1084 | exit_thread(); |
| 1080 | cgroup_exit(tsk, 1); | 1085 | cgroup_exit(tsk, 1); |
| 1081 | exit_keys(tsk); | ||
| 1082 | 1086 | ||
| 1083 | if (group_dead && tsk->signal->leader) | 1087 | if (group_dead && tsk->signal->leader) |
| 1084 | disassociate_ctty(1); | 1088 | disassociate_ctty(1); |
| @@ -1263,12 +1267,12 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
| 1263 | unsigned long state; | 1267 | unsigned long state; |
| 1264 | int retval, status, traced; | 1268 | int retval, status, traced; |
| 1265 | pid_t pid = task_pid_vnr(p); | 1269 | pid_t pid = task_pid_vnr(p); |
| 1270 | uid_t uid = __task_cred(p)->uid; | ||
| 1266 | 1271 | ||
| 1267 | if (!likely(options & WEXITED)) | 1272 | if (!likely(options & WEXITED)) |
| 1268 | return 0; | 1273 | return 0; |
| 1269 | 1274 | ||
| 1270 | if (unlikely(options & WNOWAIT)) { | 1275 | if (unlikely(options & WNOWAIT)) { |
| 1271 | uid_t uid = p->uid; | ||
| 1272 | int exit_code = p->exit_code; | 1276 | int exit_code = p->exit_code; |
| 1273 | int why, status; | 1277 | int why, status; |
| 1274 | 1278 | ||
| @@ -1389,7 +1393,7 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
| 1389 | if (!retval && infop) | 1393 | if (!retval && infop) |
| 1390 | retval = put_user(pid, &infop->si_pid); | 1394 | retval = put_user(pid, &infop->si_pid); |
| 1391 | if (!retval && infop) | 1395 | if (!retval && infop) |
| 1392 | retval = put_user(p->uid, &infop->si_uid); | 1396 | retval = put_user(uid, &infop->si_uid); |
| 1393 | if (!retval) | 1397 | if (!retval) |
| 1394 | retval = pid; | 1398 | retval = pid; |
| 1395 | 1399 | ||
| @@ -1454,7 +1458,8 @@ static int wait_task_stopped(int ptrace, struct task_struct *p, | |||
| 1454 | if (!unlikely(options & WNOWAIT)) | 1458 | if (!unlikely(options & WNOWAIT)) |
| 1455 | p->exit_code = 0; | 1459 | p->exit_code = 0; |
| 1456 | 1460 | ||
| 1457 | uid = p->uid; | 1461 | /* don't need the RCU readlock here as we're holding a spinlock */ |
| 1462 | uid = __task_cred(p)->uid; | ||
| 1458 | unlock_sig: | 1463 | unlock_sig: |
| 1459 | spin_unlock_irq(&p->sighand->siglock); | 1464 | spin_unlock_irq(&p->sighand->siglock); |
| 1460 | if (!exit_code) | 1465 | if (!exit_code) |
| @@ -1528,10 +1533,10 @@ static int wait_task_continued(struct task_struct *p, int options, | |||
| 1528 | } | 1533 | } |
| 1529 | if (!unlikely(options & WNOWAIT)) | 1534 | if (!unlikely(options & WNOWAIT)) |
| 1530 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; | 1535 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; |
| 1536 | uid = __task_cred(p)->uid; | ||
| 1531 | spin_unlock_irq(&p->sighand->siglock); | 1537 | spin_unlock_irq(&p->sighand->siglock); |
| 1532 | 1538 | ||
| 1533 | pid = task_pid_vnr(p); | 1539 | pid = task_pid_vnr(p); |
| 1534 | uid = p->uid; | ||
| 1535 | get_task_struct(p); | 1540 | get_task_struct(p); |
| 1536 | read_unlock(&tasklist_lock); | 1541 | read_unlock(&tasklist_lock); |
| 1537 | 1542 | ||
