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 ae2b92be5fae..16eda9b39f8d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -47,12 +47,14 @@ | |||
47 | #include <linux/blkdev.h> | 47 | #include <linux/blkdev.h> |
48 | #include <linux/task_io_accounting_ops.h> | 48 | #include <linux/task_io_accounting_ops.h> |
49 | #include <linux/tracehook.h> | 49 | #include <linux/tracehook.h> |
50 | #include <linux/init_task.h> | ||
50 | #include <trace/sched.h> | 51 | #include <trace/sched.h> |
51 | 52 | ||
52 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
53 | #include <asm/unistd.h> | 54 | #include <asm/unistd.h> |
54 | #include <asm/pgtable.h> | 55 | #include <asm/pgtable.h> |
55 | #include <asm/mmu_context.h> | 56 | #include <asm/mmu_context.h> |
57 | #include "cred-internals.h" | ||
56 | 58 | ||
57 | static void exit_mm(struct task_struct * tsk); | 59 | static void exit_mm(struct task_struct * tsk); |
58 | 60 | ||
@@ -165,7 +167,10 @@ void release_task(struct task_struct * p) | |||
165 | int zap_leader; | 167 | int zap_leader; |
166 | repeat: | 168 | repeat: |
167 | tracehook_prepare_release_task(p); | 169 | tracehook_prepare_release_task(p); |
168 | atomic_dec(&p->user->processes); | 170 | /* don't need to get the RCU readlock here - the process is dead and |
171 | * can't be modifying its own credentials */ | ||
172 | atomic_dec(&__task_cred(p)->user->processes); | ||
173 | |||
169 | proc_flush_task(p); | 174 | proc_flush_task(p); |
170 | write_lock_irq(&tasklist_lock); | 175 | write_lock_irq(&tasklist_lock); |
171 | tracehook_finish_release_task(p); | 176 | tracehook_finish_release_task(p); |
@@ -340,12 +345,12 @@ static void reparent_to_kthreadd(void) | |||
340 | /* cpus_allowed? */ | 345 | /* cpus_allowed? */ |
341 | /* rt_priority? */ | 346 | /* rt_priority? */ |
342 | /* signals? */ | 347 | /* signals? */ |
343 | security_task_reparent_to_init(current); | ||
344 | memcpy(current->signal->rlim, init_task.signal->rlim, | 348 | memcpy(current->signal->rlim, init_task.signal->rlim, |
345 | sizeof(current->signal->rlim)); | 349 | sizeof(current->signal->rlim)); |
346 | atomic_inc(&(INIT_USER->__count)); | 350 | |
351 | atomic_inc(&init_cred.usage); | ||
352 | commit_creds(&init_cred); | ||
347 | write_unlock_irq(&tasklist_lock); | 353 | write_unlock_irq(&tasklist_lock); |
348 | switch_uid(INIT_USER); | ||
349 | } | 354 | } |
350 | 355 | ||
351 | void __set_special_pids(struct pid *pid) | 356 | void __set_special_pids(struct pid *pid) |
@@ -1087,7 +1092,6 @@ NORET_TYPE void do_exit(long code) | |||
1087 | check_stack_usage(); | 1092 | check_stack_usage(); |
1088 | exit_thread(); | 1093 | exit_thread(); |
1089 | cgroup_exit(tsk, 1); | 1094 | cgroup_exit(tsk, 1); |
1090 | exit_keys(tsk); | ||
1091 | 1095 | ||
1092 | if (group_dead && tsk->signal->leader) | 1096 | if (group_dead && tsk->signal->leader) |
1093 | disassociate_ctty(1); | 1097 | disassociate_ctty(1); |
@@ -1272,12 +1276,12 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
1272 | unsigned long state; | 1276 | unsigned long state; |
1273 | int retval, status, traced; | 1277 | int retval, status, traced; |
1274 | pid_t pid = task_pid_vnr(p); | 1278 | pid_t pid = task_pid_vnr(p); |
1279 | uid_t uid = __task_cred(p)->uid; | ||
1275 | 1280 | ||
1276 | if (!likely(options & WEXITED)) | 1281 | if (!likely(options & WEXITED)) |
1277 | return 0; | 1282 | return 0; |
1278 | 1283 | ||
1279 | if (unlikely(options & WNOWAIT)) { | 1284 | if (unlikely(options & WNOWAIT)) { |
1280 | uid_t uid = p->uid; | ||
1281 | int exit_code = p->exit_code; | 1285 | int exit_code = p->exit_code; |
1282 | int why, status; | 1286 | int why, status; |
1283 | 1287 | ||
@@ -1398,7 +1402,7 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
1398 | if (!retval && infop) | 1402 | if (!retval && infop) |
1399 | retval = put_user(pid, &infop->si_pid); | 1403 | retval = put_user(pid, &infop->si_pid); |
1400 | if (!retval && infop) | 1404 | if (!retval && infop) |
1401 | retval = put_user(p->uid, &infop->si_uid); | 1405 | retval = put_user(uid, &infop->si_uid); |
1402 | if (!retval) | 1406 | if (!retval) |
1403 | retval = pid; | 1407 | retval = pid; |
1404 | 1408 | ||
@@ -1463,7 +1467,8 @@ static int wait_task_stopped(int ptrace, struct task_struct *p, | |||
1463 | if (!unlikely(options & WNOWAIT)) | 1467 | if (!unlikely(options & WNOWAIT)) |
1464 | p->exit_code = 0; | 1468 | p->exit_code = 0; |
1465 | 1469 | ||
1466 | uid = p->uid; | 1470 | /* don't need the RCU readlock here as we're holding a spinlock */ |
1471 | uid = __task_cred(p)->uid; | ||
1467 | unlock_sig: | 1472 | unlock_sig: |
1468 | spin_unlock_irq(&p->sighand->siglock); | 1473 | spin_unlock_irq(&p->sighand->siglock); |
1469 | if (!exit_code) | 1474 | if (!exit_code) |
@@ -1537,10 +1542,10 @@ static int wait_task_continued(struct task_struct *p, int options, | |||
1537 | } | 1542 | } |
1538 | if (!unlikely(options & WNOWAIT)) | 1543 | if (!unlikely(options & WNOWAIT)) |
1539 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; | 1544 | p->signal->flags &= ~SIGNAL_STOP_CONTINUED; |
1545 | uid = __task_cred(p)->uid; | ||
1540 | spin_unlock_irq(&p->sighand->siglock); | 1546 | spin_unlock_irq(&p->sighand->siglock); |
1541 | 1547 | ||
1542 | pid = task_pid_vnr(p); | 1548 | pid = task_pid_vnr(p); |
1543 | uid = p->uid; | ||
1544 | get_task_struct(p); | 1549 | get_task_struct(p); |
1545 | read_unlock(&tasklist_lock); | 1550 | read_unlock(&tasklist_lock); |
1546 | 1551 | ||