diff options
author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2012-10-08 19:28:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:18 -0400 |
commit | 2dd8ad81e31d0d36a5d448329c646ab43eb17788 (patch) | |
tree | cd358be45ed8067673edac7f1db6b6a42a96d9db | |
parent | 0b173bc4daa8f8ec03a85abf5e47b23502ff80af (diff) |
mm: use mm->exe_file instead of first VM_EXECUTABLE vma->vm_file
Some security modules and oprofile still uses VM_EXECUTABLE for retrieving
a task's executable file. After this patch they will use mm->exe_file
directly. mm->exe_file is protected with mm->mmap_sem, so locking stays
the same.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Acked-by: Chris Metcalf <cmetcalf@tilera.com> [arch/tile]
Acked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> [tomoyo]
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Carsten Otte <cotte@de.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Eric Paris <eparis@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Acked-by: James Morris <james.l.morris@oracle.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Kentaro Takeda <takedakn@nttdata.co.jp>
Cc: Matt Helsley <matthltc@us.ibm.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Venkatesh Pallipadi <venki@google.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/powerpc/oprofile/cell/spu_task_sync.c | 15 | ||||
-rw-r--r-- | arch/tile/mm/elf.c | 19 | ||||
-rw-r--r-- | drivers/oprofile/buffer_sync.c | 17 | ||||
-rw-r--r-- | kernel/auditsc.c | 13 | ||||
-rw-r--r-- | kernel/fork.c | 3 | ||||
-rw-r--r-- | security/tomoyo/util.c | 9 |
6 files changed, 19 insertions, 57 deletions
diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index 642fca137ccb..28f1af2db1f5 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c | |||
@@ -304,7 +304,7 @@ static inline unsigned long fast_get_dcookie(struct path *path) | |||
304 | return cookie; | 304 | return cookie; |
305 | } | 305 | } |
306 | 306 | ||
307 | /* Look up the dcookie for the task's first VM_EXECUTABLE mapping, | 307 | /* Look up the dcookie for the task's mm->exe_file, |
308 | * which corresponds loosely to "application name". Also, determine | 308 | * which corresponds loosely to "application name". Also, determine |
309 | * the offset for the SPU ELF object. If computed offset is | 309 | * the offset for the SPU ELF object. If computed offset is |
310 | * non-zero, it implies an embedded SPU object; otherwise, it's a | 310 | * non-zero, it implies an embedded SPU object; otherwise, it's a |
@@ -321,7 +321,6 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, | |||
321 | { | 321 | { |
322 | unsigned long app_cookie = 0; | 322 | unsigned long app_cookie = 0; |
323 | unsigned int my_offset = 0; | 323 | unsigned int my_offset = 0; |
324 | struct file *app = NULL; | ||
325 | struct vm_area_struct *vma; | 324 | struct vm_area_struct *vma; |
326 | struct mm_struct *mm = spu->mm; | 325 | struct mm_struct *mm = spu->mm; |
327 | 326 | ||
@@ -330,16 +329,10 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, | |||
330 | 329 | ||
331 | down_read(&mm->mmap_sem); | 330 | down_read(&mm->mmap_sem); |
332 | 331 | ||
333 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 332 | if (mm->exe_file) { |
334 | if (!vma->vm_file) | 333 | app_cookie = fast_get_dcookie(&mm->exe_file->f_path); |
335 | continue; | ||
336 | if (!(vma->vm_flags & VM_EXECUTABLE)) | ||
337 | continue; | ||
338 | app_cookie = fast_get_dcookie(&vma->vm_file->f_path); | ||
339 | pr_debug("got dcookie for %s\n", | 334 | pr_debug("got dcookie for %s\n", |
340 | vma->vm_file->f_dentry->d_name.name); | 335 | mm->exe_file->f_dentry->d_name.name); |
341 | app = vma->vm_file; | ||
342 | break; | ||
343 | } | 336 | } |
344 | 337 | ||
345 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 338 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c index 758b6038c2b7..3cfa98bf9125 100644 --- a/arch/tile/mm/elf.c +++ b/arch/tile/mm/elf.c | |||
@@ -36,19 +36,14 @@ static void sim_notify_exec(const char *binary_name) | |||
36 | } while (c); | 36 | } while (c); |
37 | } | 37 | } |
38 | 38 | ||
39 | static int notify_exec(void) | 39 | static int notify_exec(struct mm_struct *mm) |
40 | { | 40 | { |
41 | int retval = 0; /* failure */ | 41 | int retval = 0; /* failure */ |
42 | struct vm_area_struct *vma = current->mm->mmap; | 42 | |
43 | while (vma) { | 43 | if (mm->exe_file) { |
44 | if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) | ||
45 | break; | ||
46 | vma = vma->vm_next; | ||
47 | } | ||
48 | if (vma) { | ||
49 | char *buf = (char *) __get_free_page(GFP_KERNEL); | 44 | char *buf = (char *) __get_free_page(GFP_KERNEL); |
50 | if (buf) { | 45 | if (buf) { |
51 | char *path = d_path(&vma->vm_file->f_path, | 46 | char *path = d_path(&mm->exe_file->f_path, |
52 | buf, PAGE_SIZE); | 47 | buf, PAGE_SIZE); |
53 | if (!IS_ERR(path)) { | 48 | if (!IS_ERR(path)) { |
54 | sim_notify_exec(path); | 49 | sim_notify_exec(path); |
@@ -106,16 +101,16 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
106 | unsigned long vdso_base; | 101 | unsigned long vdso_base; |
107 | int retval = 0; | 102 | int retval = 0; |
108 | 103 | ||
104 | down_write(&mm->mmap_sem); | ||
105 | |||
109 | /* | 106 | /* |
110 | * Notify the simulator that an exec just occurred. | 107 | * Notify the simulator that an exec just occurred. |
111 | * If we can't find the filename of the mapping, just use | 108 | * If we can't find the filename of the mapping, just use |
112 | * whatever was passed as the linux_binprm filename. | 109 | * whatever was passed as the linux_binprm filename. |
113 | */ | 110 | */ |
114 | if (!notify_exec()) | 111 | if (!notify_exec(mm)) |
115 | sim_notify_exec(bprm->filename); | 112 | sim_notify_exec(bprm->filename); |
116 | 113 | ||
117 | down_write(&mm->mmap_sem); | ||
118 | |||
119 | /* | 114 | /* |
120 | * MAYWRITE to allow gdb to COW and set breakpoints | 115 | * MAYWRITE to allow gdb to COW and set breakpoints |
121 | */ | 116 | */ |
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index f34b5b29fb95..d93b2b6b1f7a 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
@@ -216,7 +216,7 @@ static inline unsigned long fast_get_dcookie(struct path *path) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | 218 | ||
219 | /* Look up the dcookie for the task's first VM_EXECUTABLE mapping, | 219 | /* Look up the dcookie for the task's mm->exe_file, |
220 | * which corresponds loosely to "application name". This is | 220 | * which corresponds loosely to "application name". This is |
221 | * not strictly necessary but allows oprofile to associate | 221 | * not strictly necessary but allows oprofile to associate |
222 | * shared-library samples with particular applications | 222 | * shared-library samples with particular applications |
@@ -224,21 +224,10 @@ static inline unsigned long fast_get_dcookie(struct path *path) | |||
224 | static unsigned long get_exec_dcookie(struct mm_struct *mm) | 224 | static unsigned long get_exec_dcookie(struct mm_struct *mm) |
225 | { | 225 | { |
226 | unsigned long cookie = NO_COOKIE; | 226 | unsigned long cookie = NO_COOKIE; |
227 | struct vm_area_struct *vma; | ||
228 | |||
229 | if (!mm) | ||
230 | goto out; | ||
231 | 227 | ||
232 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 228 | if (mm && mm->exe_file) |
233 | if (!vma->vm_file) | 229 | cookie = fast_get_dcookie(&mm->exe_file->f_path); |
234 | continue; | ||
235 | if (!(vma->vm_flags & VM_EXECUTABLE)) | ||
236 | continue; | ||
237 | cookie = fast_get_dcookie(&vma->vm_file->f_path); | ||
238 | break; | ||
239 | } | ||
240 | 230 | ||
241 | out: | ||
242 | return cookie; | 231 | return cookie; |
243 | } | 232 | } |
244 | 233 | ||
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 29e090cc0e46..f4a7756f999c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1151,7 +1151,6 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
1151 | const struct cred *cred; | 1151 | const struct cred *cred; |
1152 | char name[sizeof(tsk->comm)]; | 1152 | char name[sizeof(tsk->comm)]; |
1153 | struct mm_struct *mm = tsk->mm; | 1153 | struct mm_struct *mm = tsk->mm; |
1154 | struct vm_area_struct *vma; | ||
1155 | char *tty; | 1154 | char *tty; |
1156 | 1155 | ||
1157 | if (!ab) | 1156 | if (!ab) |
@@ -1191,16 +1190,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
1191 | 1190 | ||
1192 | if (mm) { | 1191 | if (mm) { |
1193 | down_read(&mm->mmap_sem); | 1192 | down_read(&mm->mmap_sem); |
1194 | vma = mm->mmap; | 1193 | if (mm->exe_file) |
1195 | while (vma) { | 1194 | audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); |
1196 | if ((vma->vm_flags & VM_EXECUTABLE) && | ||
1197 | vma->vm_file) { | ||
1198 | audit_log_d_path(ab, " exe=", | ||
1199 | &vma->vm_file->f_path); | ||
1200 | break; | ||
1201 | } | ||
1202 | vma = vma->vm_next; | ||
1203 | } | ||
1204 | up_read(&mm->mmap_sem); | 1195 | up_read(&mm->mmap_sem); |
1205 | } | 1196 | } |
1206 | audit_log_task_context(ab); | 1197 | audit_log_task_context(ab); |
diff --git a/kernel/fork.c b/kernel/fork.c index a2b1efc20928..a57a993681ed 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -656,8 +656,7 @@ struct file *get_mm_exe_file(struct mm_struct *mm) | |||
656 | { | 656 | { |
657 | struct file *exe_file; | 657 | struct file *exe_file; |
658 | 658 | ||
659 | /* We need mmap_sem to protect against races with removal of | 659 | /* We need mmap_sem to protect against races with removal of exe_file */ |
660 | * VM_EXECUTABLE vmas */ | ||
661 | down_read(&mm->mmap_sem); | 660 | down_read(&mm->mmap_sem); |
662 | exe_file = mm->exe_file; | 661 | exe_file = mm->exe_file; |
663 | if (exe_file) | 662 | if (exe_file) |
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 867558c98334..2952ba576fb9 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c | |||
@@ -949,18 +949,13 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, | |||
949 | const char *tomoyo_get_exe(void) | 949 | const char *tomoyo_get_exe(void) |
950 | { | 950 | { |
951 | struct mm_struct *mm = current->mm; | 951 | struct mm_struct *mm = current->mm; |
952 | struct vm_area_struct *vma; | ||
953 | const char *cp = NULL; | 952 | const char *cp = NULL; |
954 | 953 | ||
955 | if (!mm) | 954 | if (!mm) |
956 | return NULL; | 955 | return NULL; |
957 | down_read(&mm->mmap_sem); | 956 | down_read(&mm->mmap_sem); |
958 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 957 | if (mm->exe_file) |
959 | if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { | 958 | cp = tomoyo_realpath_from_path(&mm->exe_file->f_path); |
960 | cp = tomoyo_realpath_from_path(&vma->vm_file->f_path); | ||
961 | break; | ||
962 | } | ||
963 | } | ||
964 | up_read(&mm->mmap_sem); | 959 | up_read(&mm->mmap_sem); |
965 | return cp; | 960 | return cp; |
966 | } | 961 | } |