diff options
-rw-r--r-- | fs/exec.c | 10 | ||||
-rw-r--r-- | include/linux/mm_types.h | 2 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | kernel/exit.c | 2 | ||||
-rw-r--r-- | kernel/fork.c | 13 |
5 files changed, 15 insertions, 13 deletions
@@ -1397,10 +1397,12 @@ out_ret: | |||
1397 | 1397 | ||
1398 | void set_binfmt(struct linux_binfmt *new) | 1398 | void set_binfmt(struct linux_binfmt *new) |
1399 | { | 1399 | { |
1400 | if (current->binfmt) | 1400 | struct mm_struct *mm = current->mm; |
1401 | module_put(current->binfmt->module); | 1401 | |
1402 | if (mm->binfmt) | ||
1403 | module_put(mm->binfmt->module); | ||
1402 | 1404 | ||
1403 | current->binfmt = new; | 1405 | mm->binfmt = new; |
1404 | if (new) | 1406 | if (new) |
1405 | __module_get(new->module); | 1407 | __module_get(new->module); |
1406 | } | 1408 | } |
@@ -1770,7 +1772,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1770 | 1772 | ||
1771 | audit_core_dumps(signr); | 1773 | audit_core_dumps(signr); |
1772 | 1774 | ||
1773 | binfmt = current->binfmt; | 1775 | binfmt = mm->binfmt; |
1774 | if (!binfmt || !binfmt->core_dump) | 1776 | if (!binfmt || !binfmt->core_dump) |
1775 | goto fail; | 1777 | goto fail; |
1776 | 1778 | ||
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 6b7029ab9c8e..21d6aa45206a 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -240,6 +240,8 @@ struct mm_struct { | |||
240 | 240 | ||
241 | unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ | 241 | unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ |
242 | 242 | ||
243 | struct linux_binfmt *binfmt; | ||
244 | |||
243 | cpumask_t cpu_vm_mask; | 245 | cpumask_t cpu_vm_mask; |
244 | 246 | ||
245 | /* Architecture-specific MM context */ | 247 | /* Architecture-specific MM context */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 811cd96524d7..8a16f6d11dcd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1271,7 +1271,6 @@ struct task_struct { | |||
1271 | struct mm_struct *mm, *active_mm; | 1271 | struct mm_struct *mm, *active_mm; |
1272 | 1272 | ||
1273 | /* task state */ | 1273 | /* task state */ |
1274 | struct linux_binfmt *binfmt; | ||
1275 | int exit_state; | 1274 | int exit_state; |
1276 | int exit_code, exit_signal; | 1275 | int exit_code, exit_signal; |
1277 | int pdeath_signal; /* The signal sent when the parent dies */ | 1276 | int pdeath_signal; /* The signal sent when the parent dies */ |
diff --git a/kernel/exit.c b/kernel/exit.c index 6c75ff83a8fe..5859f598c951 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -976,8 +976,6 @@ NORET_TYPE void do_exit(long code) | |||
976 | disassociate_ctty(1); | 976 | disassociate_ctty(1); |
977 | 977 | ||
978 | module_put(task_thread_info(tsk)->exec_domain->module); | 978 | module_put(task_thread_info(tsk)->exec_domain->module); |
979 | if (tsk->binfmt) | ||
980 | module_put(tsk->binfmt->module); | ||
981 | 979 | ||
982 | proc_exit_connector(tsk); | 980 | proc_exit_connector(tsk); |
983 | 981 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index e49f181ba1ca..266c6af6ef1b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -518,6 +518,8 @@ void mmput(struct mm_struct *mm) | |||
518 | spin_unlock(&mmlist_lock); | 518 | spin_unlock(&mmlist_lock); |
519 | } | 519 | } |
520 | put_swap_token(mm); | 520 | put_swap_token(mm); |
521 | if (mm->binfmt) | ||
522 | module_put(mm->binfmt->module); | ||
521 | mmdrop(mm); | 523 | mmdrop(mm); |
522 | } | 524 | } |
523 | } | 525 | } |
@@ -643,9 +645,14 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
643 | mm->hiwater_rss = get_mm_rss(mm); | 645 | mm->hiwater_rss = get_mm_rss(mm); |
644 | mm->hiwater_vm = mm->total_vm; | 646 | mm->hiwater_vm = mm->total_vm; |
645 | 647 | ||
648 | if (mm->binfmt && !try_module_get(mm->binfmt->module)) | ||
649 | goto free_pt; | ||
650 | |||
646 | return mm; | 651 | return mm; |
647 | 652 | ||
648 | free_pt: | 653 | free_pt: |
654 | /* don't put binfmt in mmput, we haven't got module yet */ | ||
655 | mm->binfmt = NULL; | ||
649 | mmput(mm); | 656 | mmput(mm); |
650 | 657 | ||
651 | fail_nomem: | 658 | fail_nomem: |
@@ -1037,9 +1044,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1037 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) | 1044 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
1038 | goto bad_fork_cleanup_count; | 1045 | goto bad_fork_cleanup_count; |
1039 | 1046 | ||
1040 | if (p->binfmt && !try_module_get(p->binfmt->module)) | ||
1041 | goto bad_fork_cleanup_put_domain; | ||
1042 | |||
1043 | p->did_exec = 0; | 1047 | p->did_exec = 0; |
1044 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ | 1048 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
1045 | copy_flags(clone_flags, p); | 1049 | copy_flags(clone_flags, p); |
@@ -1327,9 +1331,6 @@ bad_fork_cleanup_cgroup: | |||
1327 | #endif | 1331 | #endif |
1328 | cgroup_exit(p, cgroup_callbacks_done); | 1332 | cgroup_exit(p, cgroup_callbacks_done); |
1329 | delayacct_tsk_free(p); | 1333 | delayacct_tsk_free(p); |
1330 | if (p->binfmt) | ||
1331 | module_put(p->binfmt->module); | ||
1332 | bad_fork_cleanup_put_domain: | ||
1333 | module_put(task_thread_info(p)->exec_domain->module); | 1334 | module_put(task_thread_info(p)->exec_domain->module); |
1334 | bad_fork_cleanup_count: | 1335 | bad_fork_cleanup_count: |
1335 | atomic_dec(&p->cred->user->processes); | 1336 | atomic_dec(&p->cred->user->processes); |