diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 34 |
1 files changed, 18 insertions, 16 deletions
@@ -51,6 +51,7 @@ | |||
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> |
@@ -132,6 +133,8 @@ asmlinkage long sys_uselib(const char __user * library) | |||
132 | if (IS_ERR(file)) | 133 | if (IS_ERR(file)) |
133 | goto out; | 134 | goto out; |
134 | 135 | ||
136 | fsnotify_open(file->f_path.dentry); | ||
137 | |||
135 | error = -ENOEXEC; | 138 | error = -ENOEXEC; |
136 | if(file->f_op) { | 139 | if(file->f_op) { |
137 | struct linux_binfmt * fmt; | 140 | struct linux_binfmt * fmt; |
@@ -229,13 +232,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
229 | 232 | ||
230 | static int __bprm_mm_init(struct linux_binprm *bprm) | 233 | static int __bprm_mm_init(struct linux_binprm *bprm) |
231 | { | 234 | { |
232 | int err = -ENOMEM; | 235 | int err; |
233 | struct vm_area_struct *vma = NULL; | 236 | struct vm_area_struct *vma = NULL; |
234 | struct mm_struct *mm = bprm->mm; | 237 | struct mm_struct *mm = bprm->mm; |
235 | 238 | ||
236 | bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); | 239 | bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
237 | if (!vma) | 240 | if (!vma) |
238 | goto err; | 241 | return -ENOMEM; |
239 | 242 | ||
240 | down_write(&mm->mmap_sem); | 243 | down_write(&mm->mmap_sem); |
241 | vma->vm_mm = mm; | 244 | vma->vm_mm = mm; |
@@ -248,28 +251,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
248 | */ | 251 | */ |
249 | vma->vm_end = STACK_TOP_MAX; | 252 | vma->vm_end = STACK_TOP_MAX; |
250 | vma->vm_start = vma->vm_end - PAGE_SIZE; | 253 | vma->vm_start = vma->vm_end - PAGE_SIZE; |
251 | |||
252 | vma->vm_flags = VM_STACK_FLAGS; | 254 | vma->vm_flags = VM_STACK_FLAGS; |
253 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 255 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
254 | err = insert_vm_struct(mm, vma); | 256 | err = insert_vm_struct(mm, vma); |
255 | if (err) { | 257 | if (err) |
256 | up_write(&mm->mmap_sem); | ||
257 | goto err; | 258 | goto err; |
258 | } | ||
259 | 259 | ||
260 | mm->stack_vm = mm->total_vm = 1; | 260 | mm->stack_vm = mm->total_vm = 1; |
261 | up_write(&mm->mmap_sem); | 261 | up_write(&mm->mmap_sem); |
262 | |||
263 | bprm->p = vma->vm_end - sizeof(void *); | 262 | bprm->p = vma->vm_end - sizeof(void *); |
264 | |||
265 | return 0; | 263 | return 0; |
266 | |||
267 | err: | 264 | err: |
268 | if (vma) { | 265 | up_write(&mm->mmap_sem); |
269 | bprm->vma = NULL; | 266 | bprm->vma = NULL; |
270 | kmem_cache_free(vm_area_cachep, vma); | 267 | kmem_cache_free(vm_area_cachep, vma); |
271 | } | ||
272 | |||
273 | return err; | 268 | return err; |
274 | } | 269 | } |
275 | 270 | ||
@@ -684,6 +679,8 @@ struct file *open_exec(const char *name) | |||
684 | if (IS_ERR(file)) | 679 | if (IS_ERR(file)) |
685 | return file; | 680 | return file; |
686 | 681 | ||
682 | fsnotify_open(file->f_path.dentry); | ||
683 | |||
687 | err = deny_write_access(file); | 684 | err = deny_write_access(file); |
688 | if (err) { | 685 | if (err) { |
689 | fput(file); | 686 | fput(file); |
@@ -1689,7 +1686,7 @@ int get_dumpable(struct mm_struct *mm) | |||
1689 | return (ret >= 2) ? 2 : ret; | 1686 | return (ret >= 2) ? 2 : ret; |
1690 | } | 1687 | } |
1691 | 1688 | ||
1692 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) | 1689 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
1693 | { | 1690 | { |
1694 | struct core_state core_state; | 1691 | struct core_state core_state; |
1695 | char corename[CORENAME_MAX_SIZE + 1]; | 1692 | char corename[CORENAME_MAX_SIZE + 1]; |
@@ -1773,6 +1770,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1773 | 1770 | ||
1774 | if (ispipe) { | 1771 | if (ispipe) { |
1775 | 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 | } | ||
1776 | /* Terminate the string before the first option */ | 1778 | /* Terminate the string before the first option */ |
1777 | delimit = strchr(corename, ' '); | 1779 | delimit = strchr(corename, ' '); |
1778 | if (delimit) | 1780 | if (delimit) |
@@ -1840,5 +1842,5 @@ fail_unlock: | |||
1840 | put_cred(cred); | 1842 | put_cred(cred); |
1841 | coredump_finish(mm); | 1843 | coredump_finish(mm); |
1842 | fail: | 1844 | fail: |
1843 | return retval; | 1845 | return; |
1844 | } | 1846 | } |