aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/binfmt_flat.c3
-rw-r--r--fs/exec.c2
-rw-r--r--fs/proc/base.c75
-rw-r--r--fs/proc/internal.h1
-rw-r--r--fs/proc/task_mmu.c34
-rw-r--r--fs/proc/task_nommu.c34
6 files changed, 79 insertions, 70 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index c12cc362fd3b..3b40d45a3a16 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -531,7 +531,8 @@ static int load_flat_file(struct linux_binprm * bprm,
531 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); 531 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
532 532
533 down_write(&current->mm->mmap_sem); 533 down_write(&current->mm->mmap_sem);
534 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE, 0); 534 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
535 MAP_PRIVATE|MAP_EXECUTABLE, 0);
535 up_write(&current->mm->mmap_sem); 536 up_write(&current->mm->mmap_sem);
536 if (!textpos || textpos >= (unsigned long) -4096) { 537 if (!textpos || textpos >= (unsigned long) -4096) {
537 if (!textpos) 538 if (!textpos)
diff --git a/fs/exec.c b/fs/exec.c
index 711bc45d789c..a13883903ee9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -964,6 +964,8 @@ int flush_old_exec(struct linux_binprm * bprm)
964 if (retval) 964 if (retval)
965 goto out; 965 goto out;
966 966
967 set_mm_exe_file(bprm->mm, bprm->file);
968
967 /* 969 /*
968 * Release all of the old mmap stuff 970 * Release all of the old mmap stuff
969 */ 971 */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index c5e412a00b17..b48ddb119945 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1181,6 +1181,81 @@ static const struct file_operations proc_pid_sched_operations = {
1181 1181
1182#endif 1182#endif
1183 1183
1184/*
1185 * We added or removed a vma mapping the executable. The vmas are only mapped
1186 * during exec and are not mapped with the mmap system call.
1187 * Callers must hold down_write() on the mm's mmap_sem for these
1188 */
1189void added_exe_file_vma(struct mm_struct *mm)
1190{
1191 mm->num_exe_file_vmas++;
1192}
1193
1194void removed_exe_file_vma(struct mm_struct *mm)
1195{
1196 mm->num_exe_file_vmas--;
1197 if ((mm->num_exe_file_vmas == 0) && mm->exe_file){
1198 fput(mm->exe_file);
1199 mm->exe_file = NULL;
1200 }
1201
1202}
1203
1204void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
1205{
1206 if (new_exe_file)
1207 get_file(new_exe_file);
1208 if (mm->exe_file)
1209 fput(mm->exe_file);
1210 mm->exe_file = new_exe_file;
1211 mm->num_exe_file_vmas = 0;
1212}
1213
1214struct file *get_mm_exe_file(struct mm_struct *mm)
1215{
1216 struct file *exe_file;
1217
1218 /* We need mmap_sem to protect against races with removal of
1219 * VM_EXECUTABLE vmas */
1220 down_read(&mm->mmap_sem);
1221 exe_file = mm->exe_file;
1222 if (exe_file)
1223 get_file(exe_file);
1224 up_read(&mm->mmap_sem);
1225 return exe_file;
1226}
1227
1228void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
1229{
1230 /* It's safe to write the exe_file pointer without exe_file_lock because
1231 * this is called during fork when the task is not yet in /proc */
1232 newmm->exe_file = get_mm_exe_file(oldmm);
1233}
1234
1235static int proc_exe_link(struct inode *inode, struct path *exe_path)
1236{
1237 struct task_struct *task;
1238 struct mm_struct *mm;
1239 struct file *exe_file;
1240
1241 task = get_proc_task(inode);
1242 if (!task)
1243 return -ENOENT;
1244 mm = get_task_mm(task);
1245 put_task_struct(task);
1246 if (!mm)
1247 return -ENOENT;
1248 exe_file = get_mm_exe_file(mm);
1249 mmput(mm);
1250 if (exe_file) {
1251 *exe_path = exe_file->f_path;
1252 path_get(&exe_file->f_path);
1253 fput(exe_file);
1254 return 0;
1255 } else
1256 return -ENOENT;
1257}
1258
1184static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) 1259static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1185{ 1260{
1186 struct inode *inode = dentry->d_inode; 1261 struct inode *inode = dentry->d_inode;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index bc72f5c8c47d..45abb9803988 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -48,7 +48,6 @@ extern int maps_protect;
48 48
49extern void create_seq_entry(char *name, mode_t mode, 49extern void create_seq_entry(char *name, mode_t mode,
50 const struct file_operations *f); 50 const struct file_operations *f);
51extern int proc_exe_link(struct inode *, struct path *);
52extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, 51extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
53 struct pid *pid, struct task_struct *task); 52 struct pid *pid, struct task_struct *task);
54extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, 53extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7415eeb7cc3a..e2b8e769f510 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -75,40 +75,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
75 return mm->total_vm; 75 return mm->total_vm;
76} 76}
77 77
78int proc_exe_link(struct inode *inode, struct path *path)
79{
80 struct vm_area_struct * vma;
81 int result = -ENOENT;
82 struct task_struct *task = get_proc_task(inode);
83 struct mm_struct * mm = NULL;
84
85 if (task) {
86 mm = get_task_mm(task);
87 put_task_struct(task);
88 }
89 if (!mm)
90 goto out;
91 down_read(&mm->mmap_sem);
92
93 vma = mm->mmap;
94 while (vma) {
95 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
96 break;
97 vma = vma->vm_next;
98 }
99
100 if (vma) {
101 *path = vma->vm_file->f_path;
102 path_get(&vma->vm_file->f_path);
103 result = 0;
104 }
105
106 up_read(&mm->mmap_sem);
107 mmput(mm);
108out:
109 return result;
110}
111
112static void pad_len_spaces(struct seq_file *m, int len) 78static void pad_len_spaces(struct seq_file *m, int len)
113{ 79{
114 len = 25 + sizeof(void*) * 6 - len; 80 len = 25 + sizeof(void*) * 6 - len;
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 8011528518bd..4b733f108455 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -103,40 +103,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
103 return size; 103 return size;
104} 104}
105 105
106int proc_exe_link(struct inode *inode, struct path *path)
107{
108 struct vm_list_struct *vml;
109 struct vm_area_struct *vma;
110 struct task_struct *task = get_proc_task(inode);
111 struct mm_struct *mm = get_task_mm(task);
112 int result = -ENOENT;
113
114 if (!mm)
115 goto out;
116 down_read(&mm->mmap_sem);
117
118 vml = mm->context.vmlist;
119 vma = NULL;
120 while (vml) {
121 if ((vml->vma->vm_flags & VM_EXECUTABLE) && vml->vma->vm_file) {
122 vma = vml->vma;
123 break;
124 }
125 vml = vml->next;
126 }
127
128 if (vma) {
129 *path = vma->vm_file->f_path;
130 path_get(&vma->vm_file->f_path);
131 result = 0;
132 }
133
134 up_read(&mm->mmap_sem);
135 mmput(mm);
136out:
137 return result;
138}
139
140/* 106/*
141 * display mapping lines for a particular process's /proc/pid/maps 107 * display mapping lines for a particular process's /proc/pid/maps
142 */ 108 */