aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c1
-rw-r--r--fs/proc/base.c51
-rw-r--r--include/linux/mm.h10
-rw-r--r--include/linux/mm_types.h2
-rw-r--r--include/linux/proc_fs.h19
-rw-r--r--kernel/fork.c52
6 files changed, 53 insertions, 82 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 936f5776655..88a16c57228 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -42,7 +42,6 @@
42#include <linux/pid_namespace.h> 42#include <linux/pid_namespace.h>
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/namei.h> 44#include <linux/namei.h>
45#include <linux/proc_fs.h>
46#include <linux/mount.h> 45#include <linux/mount.h>
47#include <linux/security.h> 46#include <linux/security.h>
48#include <linux/syscalls.h> 47#include <linux/syscalls.h>
diff --git a/fs/proc/base.c b/fs/proc/base.c
index dc8bca72b00..c2ac2fb123c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1576,57 +1576,6 @@ static const struct file_operations proc_pid_set_comm_operations = {
1576 .release = single_release, 1576 .release = single_release,
1577}; 1577};
1578 1578
1579/*
1580 * We added or removed a vma mapping the executable. The vmas are only mapped
1581 * during exec and are not mapped with the mmap system call.
1582 * Callers must hold down_write() on the mm's mmap_sem for these
1583 */
1584void added_exe_file_vma(struct mm_struct *mm)
1585{
1586 mm->num_exe_file_vmas++;
1587}
1588
1589void removed_exe_file_vma(struct mm_struct *mm)
1590{
1591 mm->num_exe_file_vmas--;
1592 if ((mm->num_exe_file_vmas == 0) && mm->exe_file){
1593 fput(mm->exe_file);
1594 mm->exe_file = NULL;
1595 }
1596
1597}
1598
1599void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
1600{
1601 if (new_exe_file)
1602 get_file(new_exe_file);
1603 if (mm->exe_file)
1604 fput(mm->exe_file);
1605 mm->exe_file = new_exe_file;
1606 mm->num_exe_file_vmas = 0;
1607}
1608
1609struct file *get_mm_exe_file(struct mm_struct *mm)
1610{
1611 struct file *exe_file;
1612
1613 /* We need mmap_sem to protect against races with removal of
1614 * VM_EXECUTABLE vmas */
1615 down_read(&mm->mmap_sem);
1616 exe_file = mm->exe_file;
1617 if (exe_file)
1618 get_file(exe_file);
1619 up_read(&mm->mmap_sem);
1620 return exe_file;
1621}
1622
1623void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
1624{
1625 /* It's safe to write the exe_file pointer without exe_file_lock because
1626 * this is called during fork when the task is not yet in /proc */
1627 newmm->exe_file = get_mm_exe_file(oldmm);
1628}
1629
1630static int proc_exe_link(struct inode *inode, struct path *exe_path) 1579static int proc_exe_link(struct inode *inode, struct path *exe_path)
1631{ 1580{
1632 struct task_struct *task; 1581 struct task_struct *task;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fb8e814f78d..9670f71d7be 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1408,17 +1408,11 @@ extern void exit_mmap(struct mm_struct *);
1408extern int mm_take_all_locks(struct mm_struct *mm); 1408extern int mm_take_all_locks(struct mm_struct *mm);
1409extern void mm_drop_all_locks(struct mm_struct *mm); 1409extern void mm_drop_all_locks(struct mm_struct *mm);
1410 1410
1411#ifdef CONFIG_PROC_FS
1412/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */ 1411/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
1413extern void added_exe_file_vma(struct mm_struct *mm); 1412extern void added_exe_file_vma(struct mm_struct *mm);
1414extern void removed_exe_file_vma(struct mm_struct *mm); 1413extern void removed_exe_file_vma(struct mm_struct *mm);
1415#else 1414extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
1416static inline void added_exe_file_vma(struct mm_struct *mm) 1415extern struct file *get_mm_exe_file(struct mm_struct *mm);
1417{}
1418
1419static inline void removed_exe_file_vma(struct mm_struct *mm)
1420{}
1421#endif /* CONFIG_PROC_FS */
1422 1416
1423extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); 1417extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
1424extern int install_special_mapping(struct mm_struct *mm, 1418extern int install_special_mapping(struct mm_struct *mm,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6fe96c19f85..2a78aae78c6 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -302,11 +302,9 @@ struct mm_struct {
302 struct task_struct __rcu *owner; 302 struct task_struct __rcu *owner;
303#endif 303#endif
304 304
305#ifdef CONFIG_PROC_FS
306 /* store ref to file /proc/<pid>/exe symlink points to */ 305 /* store ref to file /proc/<pid>/exe symlink points to */
307 struct file *exe_file; 306 struct file *exe_file;
308 unsigned long num_exe_file_vmas; 307 unsigned long num_exe_file_vmas;
309#endif
310#ifdef CONFIG_MMU_NOTIFIER 308#ifdef CONFIG_MMU_NOTIFIER
311 struct mmu_notifier_mm *mmu_notifier_mm; 309 struct mmu_notifier_mm *mmu_notifier_mm;
312#endif 310#endif
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 648c9c58add..e7576cf9e32 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -173,12 +173,6 @@ extern void proc_net_remove(struct net *net, const char *name);
173extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, 173extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
174 struct proc_dir_entry *parent); 174 struct proc_dir_entry *parent);
175 175
176/* While the {get|set|dup}_mm_exe_file functions are for mm_structs, they are
177 * only needed to implement /proc/<pid>|self/exe so we define them here. */
178extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
179extern struct file *get_mm_exe_file(struct mm_struct *mm);
180extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm);
181
182extern struct file *proc_ns_fget(int fd); 176extern struct file *proc_ns_fget(int fd);
183 177
184#else 178#else
@@ -230,19 +224,6 @@ static inline void pid_ns_release_proc(struct pid_namespace *ns)
230{ 224{
231} 225}
232 226
233static inline void set_mm_exe_file(struct mm_struct *mm,
234 struct file *new_exe_file)
235{}
236
237static inline struct file *get_mm_exe_file(struct mm_struct *mm)
238{
239 return NULL;
240}
241
242static inline void dup_mm_exe_file(struct mm_struct *oldmm,
243 struct mm_struct *newmm)
244{}
245
246static inline struct file *proc_ns_fget(int fd) 227static inline struct file *proc_ns_fget(int fd)
247{ 228{
248 return ERR_PTR(-EINVAL); 229 return ERR_PTR(-EINVAL);
diff --git a/kernel/fork.c b/kernel/fork.c
index 1f84099ecce..ca406d91671 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -59,7 +59,6 @@
59#include <linux/taskstats_kern.h> 59#include <linux/taskstats_kern.h>
60#include <linux/random.h> 60#include <linux/random.h>
61#include <linux/tty.h> 61#include <linux/tty.h>
62#include <linux/proc_fs.h>
63#include <linux/blkdev.h> 62#include <linux/blkdev.h>
64#include <linux/fs_struct.h> 63#include <linux/fs_struct.h>
65#include <linux/magic.h> 64#include <linux/magic.h>
@@ -597,6 +596,57 @@ void mmput(struct mm_struct *mm)
597} 596}
598EXPORT_SYMBOL_GPL(mmput); 597EXPORT_SYMBOL_GPL(mmput);
599 598
599/*
600 * We added or removed a vma mapping the executable. The vmas are only mapped
601 * during exec and are not mapped with the mmap system call.
602 * Callers must hold down_write() on the mm's mmap_sem for these
603 */
604void added_exe_file_vma(struct mm_struct *mm)
605{
606 mm->num_exe_file_vmas++;
607}
608
609void removed_exe_file_vma(struct mm_struct *mm)
610{
611 mm->num_exe_file_vmas--;
612 if ((mm->num_exe_file_vmas == 0) && mm->exe_file){
613 fput(mm->exe_file);
614 mm->exe_file = NULL;
615 }
616
617}
618
619void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
620{
621 if (new_exe_file)
622 get_file(new_exe_file);
623 if (mm->exe_file)
624 fput(mm->exe_file);
625 mm->exe_file = new_exe_file;
626 mm->num_exe_file_vmas = 0;
627}
628
629struct file *get_mm_exe_file(struct mm_struct *mm)
630{
631 struct file *exe_file;
632
633 /* We need mmap_sem to protect against races with removal of
634 * VM_EXECUTABLE vmas */
635 down_read(&mm->mmap_sem);
636 exe_file = mm->exe_file;
637 if (exe_file)
638 get_file(exe_file);
639 up_read(&mm->mmap_sem);
640 return exe_file;
641}
642
643static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
644{
645 /* It's safe to write the exe_file pointer without exe_file_lock because
646 * this is called during fork when the task is not yet in /proc */
647 newmm->exe_file = get_mm_exe_file(oldmm);
648}
649
600/** 650/**
601 * get_task_mm - acquire a reference to the task's mm 651 * get_task_mm - acquire a reference to the task's mm
602 * 652 *