diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_flat.c | 3 | ||||
-rw-r--r-- | fs/exec.c | 2 | ||||
-rw-r--r-- | fs/proc/base.c | 75 | ||||
-rw-r--r-- | fs/proc/internal.h | 1 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 34 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 34 |
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(¤t->mm->mmap_sem); | 533 | down_write(¤t->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(¤t->mm->mmap_sem); | 536 | up_write(¤t->mm->mmap_sem); |
536 | if (!textpos || textpos >= (unsigned long) -4096) { | 537 | if (!textpos || textpos >= (unsigned long) -4096) { |
537 | if (!textpos) | 538 | if (!textpos) |
@@ -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 | */ | ||
1189 | void added_exe_file_vma(struct mm_struct *mm) | ||
1190 | { | ||
1191 | mm->num_exe_file_vmas++; | ||
1192 | } | ||
1193 | |||
1194 | void 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 | |||
1204 | void 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 | |||
1214 | struct 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 | |||
1228 | void 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 | |||
1235 | static 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 | |||
1184 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 1259 | static 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 | ||
49 | extern void create_seq_entry(char *name, mode_t mode, | 49 | extern void create_seq_entry(char *name, mode_t mode, |
50 | const struct file_operations *f); | 50 | const struct file_operations *f); |
51 | extern int proc_exe_link(struct inode *, struct path *); | ||
52 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, | 51 | extern 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); |
54 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | 53 | extern 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 | ||
78 | int 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); | ||
108 | out: | ||
109 | return result; | ||
110 | } | ||
111 | |||
112 | static void pad_len_spaces(struct seq_file *m, int len) | 78 | static 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 | ||
106 | int 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); | ||
136 | out: | ||
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 | */ |