aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c78
1 files changed, 21 insertions, 57 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 02d2e120542d..71a6efe5d8bd 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -51,17 +51,13 @@
51#include <linux/audit.h> 51#include <linux/audit.h>
52#include <linux/tracehook.h> 52#include <linux/tracehook.h>
53#include <linux/kmod.h> 53#include <linux/kmod.h>
54#include <linux/fsnotify.h>
54 55
55#include <asm/uaccess.h> 56#include <asm/uaccess.h>
56#include <asm/mmu_context.h> 57#include <asm/mmu_context.h>
57#include <asm/tlb.h> 58#include <asm/tlb.h>
58#include "internal.h" 59#include "internal.h"
59 60
60#ifdef __alpha__
61/* for /sbin/loader handling in search_binary_handler() */
62#include <linux/a.out.h>
63#endif
64
65int core_uses_pid; 61int core_uses_pid;
66char core_pattern[CORENAME_MAX_SIZE] = "core"; 62char core_pattern[CORENAME_MAX_SIZE] = "core";
67int suid_dumpable = 0; 63int suid_dumpable = 0;
@@ -127,7 +123,8 @@ asmlinkage long sys_uselib(const char __user * library)
127 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 123 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
128 goto exit; 124 goto exit;
129 125
130 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); 126 error = inode_permission(nd.path.dentry->d_inode,
127 MAY_READ | MAY_EXEC | MAY_OPEN);
131 if (error) 128 if (error)
132 goto exit; 129 goto exit;
133 130
@@ -136,6 +133,8 @@ asmlinkage long sys_uselib(const char __user * library)
136 if (IS_ERR(file)) 133 if (IS_ERR(file))
137 goto out; 134 goto out;
138 135
136 fsnotify_open(file->f_path.dentry);
137
139 error = -ENOEXEC; 138 error = -ENOEXEC;
140 if(file->f_op) { 139 if(file->f_op) {
141 struct linux_binfmt * fmt; 140 struct linux_binfmt * fmt;
@@ -233,13 +232,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos,
233 232
234static int __bprm_mm_init(struct linux_binprm *bprm) 233static int __bprm_mm_init(struct linux_binprm *bprm)
235{ 234{
236 int err = -ENOMEM; 235 int err;
237 struct vm_area_struct *vma = NULL; 236 struct vm_area_struct *vma = NULL;
238 struct mm_struct *mm = bprm->mm; 237 struct mm_struct *mm = bprm->mm;
239 238
240 bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 239 bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
241 if (!vma) 240 if (!vma)
242 goto err; 241 return -ENOMEM;
243 242
244 down_write(&mm->mmap_sem); 243 down_write(&mm->mmap_sem);
245 vma->vm_mm = mm; 244 vma->vm_mm = mm;
@@ -252,28 +251,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
252 */ 251 */
253 vma->vm_end = STACK_TOP_MAX; 252 vma->vm_end = STACK_TOP_MAX;
254 vma->vm_start = vma->vm_end - PAGE_SIZE; 253 vma->vm_start = vma->vm_end - PAGE_SIZE;
255
256 vma->vm_flags = VM_STACK_FLAGS; 254 vma->vm_flags = VM_STACK_FLAGS;
257 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 255 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
258 err = insert_vm_struct(mm, vma); 256 err = insert_vm_struct(mm, vma);
259 if (err) { 257 if (err)
260 up_write(&mm->mmap_sem);
261 goto err; 258 goto err;
262 }
263 259
264 mm->stack_vm = mm->total_vm = 1; 260 mm->stack_vm = mm->total_vm = 1;
265 up_write(&mm->mmap_sem); 261 up_write(&mm->mmap_sem);
266
267 bprm->p = vma->vm_end - sizeof(void *); 262 bprm->p = vma->vm_end - sizeof(void *);
268
269 return 0; 263 return 0;
270
271err: 264err:
272 if (vma) { 265 up_write(&mm->mmap_sem);
273 bprm->vma = NULL; 266 bprm->vma = NULL;
274 kmem_cache_free(vm_area_cachep, vma); 267 kmem_cache_free(vm_area_cachep, vma);
275 }
276
277 return err; 268 return err;
278} 269}
279 270
@@ -680,7 +671,7 @@ struct file *open_exec(const char *name)
680 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 671 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
681 goto out_path_put; 672 goto out_path_put;
682 673
683 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); 674 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
684 if (err) 675 if (err)
685 goto out_path_put; 676 goto out_path_put;
686 677
@@ -688,6 +679,8 @@ struct file *open_exec(const char *name)
688 if (IS_ERR(file)) 679 if (IS_ERR(file))
689 return file; 680 return file;
690 681
682 fsnotify_open(file->f_path.dentry);
683
691 err = deny_write_access(file); 684 err = deny_write_access(file);
692 if (err) { 685 if (err) {
693 fput(file); 686 fput(file);
@@ -1171,41 +1164,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1171 unsigned int depth = bprm->recursion_depth; 1164 unsigned int depth = bprm->recursion_depth;
1172 int try,retval; 1165 int try,retval;
1173 struct linux_binfmt *fmt; 1166 struct linux_binfmt *fmt;
1174#ifdef __alpha__
1175 /* handle /sbin/loader.. */
1176 {
1177 struct exec * eh = (struct exec *) bprm->buf;
1178
1179 if (!bprm->loader && eh->fh.f_magic == 0x183 &&
1180 (eh->fh.f_flags & 0x3000) == 0x3000)
1181 {
1182 struct file * file;
1183 unsigned long loader;
1184 1167
1185 allow_write_access(bprm->file);
1186 fput(bprm->file);
1187 bprm->file = NULL;
1188
1189 loader = bprm->vma->vm_end - sizeof(void *);
1190
1191 file = open_exec("/sbin/loader");
1192 retval = PTR_ERR(file);
1193 if (IS_ERR(file))
1194 return retval;
1195
1196 /* Remember if the application is TASO. */
1197 bprm->taso = eh->ah.entry < 0x100000000UL;
1198
1199 bprm->file = file;
1200 bprm->loader = loader;
1201 retval = prepare_binprm(bprm);
1202 if (retval<0)
1203 return retval;
1204 /* should call search_binary_handler recursively here,
1205 but it does not matter */
1206 }
1207 }
1208#endif
1209 retval = security_bprm_check(bprm); 1168 retval = security_bprm_check(bprm);
1210 if (retval) 1169 if (retval)
1211 return retval; 1170 return retval;
@@ -1727,7 +1686,7 @@ int get_dumpable(struct mm_struct *mm)
1727 return (ret >= 2) ? 2 : ret; 1686 return (ret >= 2) ? 2 : ret;
1728} 1687}
1729 1688
1730int do_coredump(long signr, int exit_code, struct pt_regs * regs) 1689void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1731{ 1690{
1732 struct core_state core_state; 1691 struct core_state core_state;
1733 char corename[CORENAME_MAX_SIZE + 1]; 1692 char corename[CORENAME_MAX_SIZE + 1];
@@ -1811,6 +1770,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1811 1770
1812 if (ispipe) { 1771 if (ispipe) {
1813 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); 1772 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
1773 if (!helper_argv) {
1774 printk(KERN_WARNING "%s failed to allocate memory\n",
1775 __func__);
1776 goto fail_unlock;
1777 }
1814 /* Terminate the string before the first option */ 1778 /* Terminate the string before the first option */
1815 delimit = strchr(corename, ' '); 1779 delimit = strchr(corename, ' ');
1816 if (delimit) 1780 if (delimit)
@@ -1878,5 +1842,5 @@ fail_unlock:
1878 put_cred(cred); 1842 put_cred(cred);
1879 coredump_finish(mm); 1843 coredump_finish(mm);
1880fail: 1844fail:
1881 return retval; 1845 return;
1882} 1846}