aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-17 09:04:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-17 09:04:38 -0400
commit54e514b91b95d6441c12a7955addfb9f9d2afc65 (patch)
tree8b73d901bd2a6ec5a31f34a8954e5ea92216dd6c /kernel
parent4fc8adcfec3da639da76e8314c9ccefe5bf9a045 (diff)
parent6c8c90319c0bb1c9e0b68e721359b89ae4f28465 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge third patchbomb from Andrew Morton: - various misc things - a couple of lib/ optimisations - provide DIV_ROUND_CLOSEST_ULL() - checkpatch updates - rtc tree - befs, nilfs2, hfs, hfsplus, fatfs, adfs, affs, bfs - ptrace fixes - fork() fixes - seccomp cleanups - more mmap_sem hold time reductions from Davidlohr * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (138 commits) proc: show locks in /proc/pid/fdinfo/X docs: add missing and new /proc/PID/status file entries, fix typos drivers/rtc/rtc-at91rm9200.c: make IO endian agnostic Documentation/spi/spidev_test.c: fix warning drivers/rtc/rtc-s5m.c: allow usage on device type different than main MFD type .gitignore: ignore *.tar MAINTAINERS: add Mediatek SoC mailing list tomoyo: reduce mmap_sem hold for mm->exe_file powerpc/oprofile: reduce mmap_sem hold for exe_file oprofile: reduce mmap_sem hold for mm->exe_file mips: ip32: add platform data hooks to use DS1685 driver lib/Kconfig: fix up HAVE_ARCH_BITREVERSE help text x86: switch to using asm-generic for seccomp.h sparc: switch to using asm-generic for seccomp.h powerpc: switch to using asm-generic for seccomp.h parisc: switch to using asm-generic for seccomp.h mips: switch to using asm-generic for seccomp.h microblaze: use asm-generic for seccomp.h arm: use asm-generic for seccomp.h seccomp: allow COMPAT sigreturn overrides ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c141
-rw-r--r--kernel/gcov/base.c5
-rw-r--r--kernel/pid.c15
-rw-r--r--kernel/ptrace.c39
-rw-r--r--kernel/signal.c14
-rw-r--r--kernel/sys.c47
-rw-r--r--kernel/sysctl.c16
7 files changed, 192 insertions, 85 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index f2c1e7352298..03c1eaaa6ef5 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -74,6 +74,7 @@
74#include <linux/uprobes.h> 74#include <linux/uprobes.h>
75#include <linux/aio.h> 75#include <linux/aio.h>
76#include <linux/compiler.h> 76#include <linux/compiler.h>
77#include <linux/sysctl.h>
77 78
78#include <asm/pgtable.h> 79#include <asm/pgtable.h>
79#include <asm/pgalloc.h> 80#include <asm/pgalloc.h>
@@ -88,6 +89,16 @@
88#include <trace/events/task.h> 89#include <trace/events/task.h>
89 90
90/* 91/*
92 * Minimum number of threads to boot the kernel
93 */
94#define MIN_THREADS 20
95
96/*
97 * Maximum number of threads
98 */
99#define MAX_THREADS FUTEX_TID_MASK
100
101/*
91 * Protected counters by write_lock_irq(&tasklist_lock) 102 * Protected counters by write_lock_irq(&tasklist_lock)
92 */ 103 */
93unsigned long total_forks; /* Handle normal Linux uptimes. */ 104unsigned long total_forks; /* Handle normal Linux uptimes. */
@@ -253,7 +264,30 @@ EXPORT_SYMBOL_GPL(__put_task_struct);
253 264
254void __init __weak arch_task_cache_init(void) { } 265void __init __weak arch_task_cache_init(void) { }
255 266
256void __init fork_init(unsigned long mempages) 267/*
268 * set_max_threads
269 */
270static void set_max_threads(unsigned int max_threads_suggested)
271{
272 u64 threads;
273
274 /*
275 * The number of threads shall be limited such that the thread
276 * structures may only consume a small part of the available memory.
277 */
278 if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64)
279 threads = MAX_THREADS;
280 else
281 threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
282 (u64) THREAD_SIZE * 8UL);
283
284 if (threads > max_threads_suggested)
285 threads = max_threads_suggested;
286
287 max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
288}
289
290void __init fork_init(void)
257{ 291{
258#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR 292#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
259#ifndef ARCH_MIN_TASKALIGN 293#ifndef ARCH_MIN_TASKALIGN
@@ -268,18 +302,7 @@ void __init fork_init(unsigned long mempages)
268 /* do the arch specific task caches init */ 302 /* do the arch specific task caches init */
269 arch_task_cache_init(); 303 arch_task_cache_init();
270 304
271 /* 305 set_max_threads(MAX_THREADS);
272 * The default maximum number of threads is set to a safe
273 * value: the thread structures can take up at most half
274 * of memory.
275 */
276 max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
277
278 /*
279 * we need to allow at least 20 threads to boot a system
280 */
281 if (max_threads < 20)
282 max_threads = 20;
283 306
284 init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; 307 init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
285 init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; 308 init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
@@ -380,6 +403,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
380 */ 403 */
381 down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); 404 down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING);
382 405
406 /* No ordering required: file already has been exposed. */
407 RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm));
408
383 mm->total_vm = oldmm->total_vm; 409 mm->total_vm = oldmm->total_vm;
384 mm->shared_vm = oldmm->shared_vm; 410 mm->shared_vm = oldmm->shared_vm;
385 mm->exec_vm = oldmm->exec_vm; 411 mm->exec_vm = oldmm->exec_vm;
@@ -505,7 +531,13 @@ static inline void mm_free_pgd(struct mm_struct *mm)
505 pgd_free(mm, mm->pgd); 531 pgd_free(mm, mm->pgd);
506} 532}
507#else 533#else
508#define dup_mmap(mm, oldmm) (0) 534static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
535{
536 down_write(&oldmm->mmap_sem);
537 RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm));
538 up_write(&oldmm->mmap_sem);
539 return 0;
540}
509#define mm_alloc_pgd(mm) (0) 541#define mm_alloc_pgd(mm) (0)
510#define mm_free_pgd(mm) 542#define mm_free_pgd(mm)
511#endif /* CONFIG_MMU */ 543#endif /* CONFIG_MMU */
@@ -674,34 +706,53 @@ void mmput(struct mm_struct *mm)
674} 706}
675EXPORT_SYMBOL_GPL(mmput); 707EXPORT_SYMBOL_GPL(mmput);
676 708
709/**
710 * set_mm_exe_file - change a reference to the mm's executable file
711 *
712 * This changes mm's executable file (shown as symlink /proc/[pid]/exe).
713 *
714 * Main users are mmput() and sys_execve(). Callers prevent concurrent
715 * invocations: in mmput() nobody alive left, in execve task is single
716 * threaded. sys_prctl(PR_SET_MM_MAP/EXE_FILE) also needs to set the
717 * mm->exe_file, but does so without using set_mm_exe_file() in order
718 * to do avoid the need for any locks.
719 */
677void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) 720void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
678{ 721{
722 struct file *old_exe_file;
723
724 /*
725 * It is safe to dereference the exe_file without RCU as
726 * this function is only called if nobody else can access
727 * this mm -- see comment above for justification.
728 */
729 old_exe_file = rcu_dereference_raw(mm->exe_file);
730
679 if (new_exe_file) 731 if (new_exe_file)
680 get_file(new_exe_file); 732 get_file(new_exe_file);
681 if (mm->exe_file) 733 rcu_assign_pointer(mm->exe_file, new_exe_file);
682 fput(mm->exe_file); 734 if (old_exe_file)
683 mm->exe_file = new_exe_file; 735 fput(old_exe_file);
684} 736}
685 737
738/**
739 * get_mm_exe_file - acquire a reference to the mm's executable file
740 *
741 * Returns %NULL if mm has no associated executable file.
742 * User must release file via fput().
743 */
686struct file *get_mm_exe_file(struct mm_struct *mm) 744struct file *get_mm_exe_file(struct mm_struct *mm)
687{ 745{
688 struct file *exe_file; 746 struct file *exe_file;
689 747
690 /* We need mmap_sem to protect against races with removal of exe_file */ 748 rcu_read_lock();
691 down_read(&mm->mmap_sem); 749 exe_file = rcu_dereference(mm->exe_file);
692 exe_file = mm->exe_file; 750 if (exe_file && !get_file_rcu(exe_file))
693 if (exe_file) 751 exe_file = NULL;
694 get_file(exe_file); 752 rcu_read_unlock();
695 up_read(&mm->mmap_sem);
696 return exe_file; 753 return exe_file;
697} 754}
698 755EXPORT_SYMBOL(get_mm_exe_file);
699static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
700{
701 /* It's safe to write the exe_file pointer without exe_file_lock because
702 * this is called during fork when the task is not yet in /proc */
703 newmm->exe_file = get_mm_exe_file(oldmm);
704}
705 756
706/** 757/**
707 * get_task_mm - acquire a reference to the task's mm 758 * get_task_mm - acquire a reference to the task's mm
@@ -864,8 +915,6 @@ static struct mm_struct *dup_mm(struct task_struct *tsk)
864 if (!mm_init(mm, tsk)) 915 if (!mm_init(mm, tsk))
865 goto fail_nomem; 916 goto fail_nomem;
866 917
867 dup_mm_exe_file(oldmm, mm);
868
869 err = dup_mmap(mm, oldmm); 918 err = dup_mmap(mm, oldmm);
870 if (err) 919 if (err)
871 goto free_pt; 920 goto free_pt;
@@ -1403,10 +1452,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1403 goto bad_fork_cleanup_io; 1452 goto bad_fork_cleanup_io;
1404 1453
1405 if (pid != &init_struct_pid) { 1454 if (pid != &init_struct_pid) {
1406 retval = -ENOMEM;
1407 pid = alloc_pid(p->nsproxy->pid_ns_for_children); 1455 pid = alloc_pid(p->nsproxy->pid_ns_for_children);
1408 if (!pid) 1456 if (IS_ERR(pid)) {
1457 retval = PTR_ERR(pid);
1409 goto bad_fork_cleanup_io; 1458 goto bad_fork_cleanup_io;
1459 }
1410 } 1460 }
1411 1461
1412 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; 1462 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
@@ -2000,3 +2050,26 @@ int unshare_files(struct files_struct **displaced)
2000 task_unlock(task); 2050 task_unlock(task);
2001 return 0; 2051 return 0;
2002} 2052}
2053
2054int sysctl_max_threads(struct ctl_table *table, int write,
2055 void __user *buffer, size_t *lenp, loff_t *ppos)
2056{
2057 struct ctl_table t;
2058 int ret;
2059 int threads = max_threads;
2060 int min = MIN_THREADS;
2061 int max = MAX_THREADS;
2062
2063 t = *table;
2064 t.data = &threads;
2065 t.extra1 = &min;
2066 t.extra2 = &max;
2067
2068 ret = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
2069 if (ret || !write)
2070 return ret;
2071
2072 set_max_threads(threads);
2073
2074 return 0;
2075}
diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c
index b358a802fd18..a744098e4eb7 100644
--- a/kernel/gcov/base.c
+++ b/kernel/gcov/base.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/mutex.h> 20#include <linux/mutex.h>
21#include <linux/sched.h>
21#include "gcov.h" 22#include "gcov.h"
22 23
23static int gcov_events_enabled; 24static int gcov_events_enabled;
@@ -107,8 +108,10 @@ void gcov_enable_events(void)
107 gcov_events_enabled = 1; 108 gcov_events_enabled = 1;
108 109
109 /* Perform event callback for previously registered entries. */ 110 /* Perform event callback for previously registered entries. */
110 while ((info = gcov_info_next(info))) 111 while ((info = gcov_info_next(info))) {
111 gcov_event(GCOV_ADD, info); 112 gcov_event(GCOV_ADD, info);
113 cond_resched();
114 }
112 115
113 mutex_unlock(&gcov_lock); 116 mutex_unlock(&gcov_lock);
114} 117}
diff --git a/kernel/pid.c b/kernel/pid.c
index cd36a5e0d173..4fd07d5b7baf 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -182,7 +182,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
182 spin_unlock_irq(&pidmap_lock); 182 spin_unlock_irq(&pidmap_lock);
183 kfree(page); 183 kfree(page);
184 if (unlikely(!map->page)) 184 if (unlikely(!map->page))
185 break; 185 return -ENOMEM;
186 } 186 }
187 if (likely(atomic_read(&map->nr_free))) { 187 if (likely(atomic_read(&map->nr_free))) {
188 for ( ; ; ) { 188 for ( ; ; ) {
@@ -210,7 +210,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns)
210 } 210 }
211 pid = mk_pid(pid_ns, map, offset); 211 pid = mk_pid(pid_ns, map, offset);
212 } 212 }
213 return -1; 213 return -EAGAIN;
214} 214}
215 215
216int next_pidmap(struct pid_namespace *pid_ns, unsigned int last) 216int next_pidmap(struct pid_namespace *pid_ns, unsigned int last)
@@ -301,17 +301,20 @@ struct pid *alloc_pid(struct pid_namespace *ns)
301 int i, nr; 301 int i, nr;
302 struct pid_namespace *tmp; 302 struct pid_namespace *tmp;
303 struct upid *upid; 303 struct upid *upid;
304 int retval = -ENOMEM;
304 305
305 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); 306 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
306 if (!pid) 307 if (!pid)
307 goto out; 308 return ERR_PTR(retval);
308 309
309 tmp = ns; 310 tmp = ns;
310 pid->level = ns->level; 311 pid->level = ns->level;
311 for (i = ns->level; i >= 0; i--) { 312 for (i = ns->level; i >= 0; i--) {
312 nr = alloc_pidmap(tmp); 313 nr = alloc_pidmap(tmp);
313 if (nr < 0) 314 if (IS_ERR_VALUE(nr)) {
315 retval = nr;
314 goto out_free; 316 goto out_free;
317 }
315 318
316 pid->numbers[i].nr = nr; 319 pid->numbers[i].nr = nr;
317 pid->numbers[i].ns = tmp; 320 pid->numbers[i].ns = tmp;
@@ -339,7 +342,6 @@ struct pid *alloc_pid(struct pid_namespace *ns)
339 } 342 }
340 spin_unlock_irq(&pidmap_lock); 343 spin_unlock_irq(&pidmap_lock);
341 344
342out:
343 return pid; 345 return pid;
344 346
345out_unlock: 347out_unlock:
@@ -351,8 +353,7 @@ out_free:
351 free_pidmap(pid->numbers + i); 353 free_pidmap(pid->numbers + i);
352 354
353 kmem_cache_free(ns->pid_cachep, pid); 355 kmem_cache_free(ns->pid_cachep, pid);
354 pid = NULL; 356 return ERR_PTR(retval);
355 goto out;
356} 357}
357 358
358void disable_pid_allocation(struct pid_namespace *ns) 359void disable_pid_allocation(struct pid_namespace *ns)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 227fec36b12a..c8e0e050a36a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -456,8 +456,6 @@ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
456 456
457static int ptrace_detach(struct task_struct *child, unsigned int data) 457static int ptrace_detach(struct task_struct *child, unsigned int data)
458{ 458{
459 bool dead = false;
460
461 if (!valid_signal(data)) 459 if (!valid_signal(data))
462 return -EIO; 460 return -EIO;
463 461
@@ -467,18 +465,19 @@ static int ptrace_detach(struct task_struct *child, unsigned int data)
467 465
468 write_lock_irq(&tasklist_lock); 466 write_lock_irq(&tasklist_lock);
469 /* 467 /*
470 * This child can be already killed. Make sure de_thread() or 468 * We rely on ptrace_freeze_traced(). It can't be killed and
471 * our sub-thread doing do_wait() didn't do release_task() yet. 469 * untraced by another thread, it can't be a zombie.
472 */ 470 */
473 if (child->ptrace) { 471 WARN_ON(!child->ptrace || child->exit_state);
474 child->exit_code = data; 472 /*
475 dead = __ptrace_detach(current, child); 473 * tasklist_lock avoids the race with wait_task_stopped(), see
476 } 474 * the comment in ptrace_resume().
475 */
476 child->exit_code = data;
477 __ptrace_detach(current, child);
477 write_unlock_irq(&tasklist_lock); 478 write_unlock_irq(&tasklist_lock);
478 479
479 proc_ptrace_connector(child, PTRACE_DETACH); 480 proc_ptrace_connector(child, PTRACE_DETACH);
480 if (unlikely(dead))
481 release_task(child);
482 481
483 return 0; 482 return 0;
484} 483}
@@ -697,6 +696,8 @@ static int ptrace_peek_siginfo(struct task_struct *child,
697static int ptrace_resume(struct task_struct *child, long request, 696static int ptrace_resume(struct task_struct *child, long request,
698 unsigned long data) 697 unsigned long data)
699{ 698{
699 bool need_siglock;
700
700 if (!valid_signal(data)) 701 if (!valid_signal(data))
701 return -EIO; 702 return -EIO;
702 703
@@ -724,8 +725,26 @@ static int ptrace_resume(struct task_struct *child, long request,
724 user_disable_single_step(child); 725 user_disable_single_step(child);
725 } 726 }
726 727
728 /*
729 * Change ->exit_code and ->state under siglock to avoid the race
730 * with wait_task_stopped() in between; a non-zero ->exit_code will
731 * wrongly look like another report from tracee.
732 *
733 * Note that we need siglock even if ->exit_code == data and/or this
734 * status was not reported yet, the new status must not be cleared by
735 * wait_task_stopped() after resume.
736 *
737 * If data == 0 we do not care if wait_task_stopped() reports the old
738 * status and clears the code too; this can't race with the tracee, it
739 * takes siglock after resume.
740 */
741 need_siglock = data && !thread_group_empty(current);
742 if (need_siglock)
743 spin_lock_irq(&child->sighand->siglock);
727 child->exit_code = data; 744 child->exit_code = data;
728 wake_up_state(child, __TASK_TRACED); 745 wake_up_state(child, __TASK_TRACED);
746 if (need_siglock)
747 spin_unlock_irq(&child->sighand->siglock);
729 748
730 return 0; 749 return 0;
731} 750}
diff --git a/kernel/signal.c b/kernel/signal.c
index a390499943e4..d51c5ddd855c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2992,11 +2992,9 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
2992 * Nor can they impersonate a kill()/tgkill(), which adds source info. 2992 * Nor can they impersonate a kill()/tgkill(), which adds source info.
2993 */ 2993 */
2994 if ((info->si_code >= 0 || info->si_code == SI_TKILL) && 2994 if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
2995 (task_pid_vnr(current) != pid)) { 2995 (task_pid_vnr(current) != pid))
2996 /* We used to allow any < 0 si_code */
2997 WARN_ON_ONCE(info->si_code < 0);
2998 return -EPERM; 2996 return -EPERM;
2999 } 2997
3000 info->si_signo = sig; 2998 info->si_signo = sig;
3001 2999
3002 /* POSIX.1b doesn't mention process groups. */ 3000 /* POSIX.1b doesn't mention process groups. */
@@ -3041,12 +3039,10 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
3041 /* Not even root can pretend to send signals from the kernel. 3039 /* Not even root can pretend to send signals from the kernel.
3042 * Nor can they impersonate a kill()/tgkill(), which adds source info. 3040 * Nor can they impersonate a kill()/tgkill(), which adds source info.
3043 */ 3041 */
3044 if (((info->si_code >= 0 || info->si_code == SI_TKILL)) && 3042 if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
3045 (task_pid_vnr(current) != pid)) { 3043 (task_pid_vnr(current) != pid))
3046 /* We used to allow any < 0 si_code */
3047 WARN_ON_ONCE(info->si_code < 0);
3048 return -EPERM; 3044 return -EPERM;
3049 } 3045
3050 info->si_signo = sig; 3046 info->si_signo = sig;
3051 3047
3052 return do_send_specific(tgid, pid, sig, info); 3048 return do_send_specific(tgid, pid, sig, info);
diff --git a/kernel/sys.c b/kernel/sys.c
index 3be344902316..a4e372b798a5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1649,14 +1649,13 @@ SYSCALL_DEFINE1(umask, int, mask)
1649 return mask; 1649 return mask;
1650} 1650}
1651 1651
1652static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd) 1652static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
1653{ 1653{
1654 struct fd exe; 1654 struct fd exe;
1655 struct file *old_exe, *exe_file;
1655 struct inode *inode; 1656 struct inode *inode;
1656 int err; 1657 int err;
1657 1658
1658 VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_sem), mm);
1659
1660 exe = fdget(fd); 1659 exe = fdget(fd);
1661 if (!exe.file) 1660 if (!exe.file)
1662 return -EBADF; 1661 return -EBADF;
@@ -1680,15 +1679,22 @@ static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd)
1680 /* 1679 /*
1681 * Forbid mm->exe_file change if old file still mapped. 1680 * Forbid mm->exe_file change if old file still mapped.
1682 */ 1681 */
1682 exe_file = get_mm_exe_file(mm);
1683 err = -EBUSY; 1683 err = -EBUSY;
1684 if (mm->exe_file) { 1684 if (exe_file) {
1685 struct vm_area_struct *vma; 1685 struct vm_area_struct *vma;
1686 1686
1687 for (vma = mm->mmap; vma; vma = vma->vm_next) 1687 down_read(&mm->mmap_sem);
1688 if (vma->vm_file && 1688 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1689 path_equal(&vma->vm_file->f_path, 1689 if (!vma->vm_file)
1690 &mm->exe_file->f_path)) 1690 continue;
1691 goto exit; 1691 if (path_equal(&vma->vm_file->f_path,
1692 &exe_file->f_path))
1693 goto exit_err;
1694 }
1695
1696 up_read(&mm->mmap_sem);
1697 fput(exe_file);
1692 } 1698 }
1693 1699
1694 /* 1700 /*
@@ -1702,10 +1708,18 @@ static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd)
1702 goto exit; 1708 goto exit;
1703 1709
1704 err = 0; 1710 err = 0;
1705 set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */ 1711 /* set the new file, lockless */
1712 get_file(exe.file);
1713 old_exe = xchg(&mm->exe_file, exe.file);
1714 if (old_exe)
1715 fput(old_exe);
1706exit: 1716exit:
1707 fdput(exe); 1717 fdput(exe);
1708 return err; 1718 return err;
1719exit_err:
1720 up_read(&mm->mmap_sem);
1721 fput(exe_file);
1722 goto exit;
1709} 1723}
1710 1724
1711#ifdef CONFIG_CHECKPOINT_RESTORE 1725#ifdef CONFIG_CHECKPOINT_RESTORE
@@ -1840,10 +1854,9 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
1840 user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL; 1854 user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
1841 } 1855 }
1842 1856
1843 down_write(&mm->mmap_sem);
1844 if (prctl_map.exe_fd != (u32)-1) 1857 if (prctl_map.exe_fd != (u32)-1)
1845 error = prctl_set_mm_exe_file_locked(mm, prctl_map.exe_fd); 1858 error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
1846 downgrade_write(&mm->mmap_sem); 1859 down_read(&mm->mmap_sem);
1847 if (error) 1860 if (error)
1848 goto out; 1861 goto out;
1849 1862
@@ -1909,12 +1922,8 @@ static int prctl_set_mm(int opt, unsigned long addr,
1909 if (!capable(CAP_SYS_RESOURCE)) 1922 if (!capable(CAP_SYS_RESOURCE))
1910 return -EPERM; 1923 return -EPERM;
1911 1924
1912 if (opt == PR_SET_MM_EXE_FILE) { 1925 if (opt == PR_SET_MM_EXE_FILE)
1913 down_write(&mm->mmap_sem); 1926 return prctl_set_mm_exe_file(mm, (unsigned int)addr);
1914 error = prctl_set_mm_exe_file_locked(mm, (unsigned int)addr);
1915 up_write(&mm->mmap_sem);
1916 return error;
1917 }
1918 1927
1919 if (addr >= TASK_SIZE || addr < mmap_min_addr) 1928 if (addr >= TASK_SIZE || addr < mmap_min_addr)
1920 return -EINVAL; 1929 return -EINVAL;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 42b7fc2860c1..2082b1a88fb9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -93,11 +93,9 @@
93#include <linux/nmi.h> 93#include <linux/nmi.h>
94#endif 94#endif
95 95
96
97#if defined(CONFIG_SYSCTL) 96#if defined(CONFIG_SYSCTL)
98 97
99/* External variables not in a header file. */ 98/* External variables not in a header file. */
100extern int max_threads;
101extern int suid_dumpable; 99extern int suid_dumpable;
102#ifdef CONFIG_COREDUMP 100#ifdef CONFIG_COREDUMP
103extern int core_uses_pid; 101extern int core_uses_pid;
@@ -710,10 +708,10 @@ static struct ctl_table kern_table[] = {
710#endif 708#endif
711 { 709 {
712 .procname = "threads-max", 710 .procname = "threads-max",
713 .data = &max_threads, 711 .data = NULL,
714 .maxlen = sizeof(int), 712 .maxlen = sizeof(int),
715 .mode = 0644, 713 .mode = 0644,
716 .proc_handler = proc_dointvec, 714 .proc_handler = sysctl_max_threads,
717 }, 715 },
718 { 716 {
719 .procname = "random", 717 .procname = "random",
@@ -1983,7 +1981,15 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
1983 int write, void *data) 1981 int write, void *data)
1984{ 1982{
1985 if (write) { 1983 if (write) {
1986 *valp = *negp ? -*lvalp : *lvalp; 1984 if (*negp) {
1985 if (*lvalp > (unsigned long) INT_MAX + 1)
1986 return -EINVAL;
1987 *valp = -*lvalp;
1988 } else {
1989 if (*lvalp > (unsigned long) INT_MAX)
1990 return -EINVAL;
1991 *valp = *lvalp;
1992 }
1987 } else { 1993 } else {
1988 int val = *valp; 1994 int val = *valp;
1989 if (val < 0) { 1995 if (val < 0) {