aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c80
1 files changed, 22 insertions, 58 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 9c789a525cc4..febfd8ed6ad1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -52,17 +52,13 @@
52#include <linux/audit.h> 52#include <linux/audit.h>
53#include <linux/tracehook.h> 53#include <linux/tracehook.h>
54#include <linux/kmod.h> 54#include <linux/kmod.h>
55#include <linux/fsnotify.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
57#include <asm/mmu_context.h> 58#include <asm/mmu_context.h>
58#include <asm/tlb.h> 59#include <asm/tlb.h>
59#include "internal.h" 60#include "internal.h"
60 61
61#ifdef __alpha__
62/* for /sbin/loader handling in search_binary_handler() */
63#include <linux/a.out.h>
64#endif
65
66int core_uses_pid; 62int core_uses_pid;
67char core_pattern[CORENAME_MAX_SIZE] = "core"; 63char core_pattern[CORENAME_MAX_SIZE] = "core";
68int suid_dumpable = 0; 64int suid_dumpable = 0;
@@ -104,7 +100,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
104 * 100 *
105 * Also note that we take the address to load from from the file itself. 101 * Also note that we take the address to load from from the file itself.
106 */ 102 */
107asmlinkage long sys_uselib(const char __user * library) 103SYSCALL_DEFINE1(uselib, const char __user *, library)
108{ 104{
109 struct file *file; 105 struct file *file;
110 struct nameidata nd; 106 struct nameidata nd;
@@ -128,7 +124,8 @@ asmlinkage long sys_uselib(const char __user * library)
128 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 124 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
129 goto exit; 125 goto exit;
130 126
131 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); 127 error = inode_permission(nd.path.dentry->d_inode,
128 MAY_READ | MAY_EXEC | MAY_OPEN);
132 if (error) 129 if (error)
133 goto exit; 130 goto exit;
134 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN); 131 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
@@ -140,6 +137,8 @@ asmlinkage long sys_uselib(const char __user * library)
140 if (IS_ERR(file)) 137 if (IS_ERR(file))
141 goto out; 138 goto out;
142 139
140 fsnotify_open(file->f_path.dentry);
141
143 error = -ENOEXEC; 142 error = -ENOEXEC;
144 if(file->f_op) { 143 if(file->f_op) {
145 struct linux_binfmt * fmt; 144 struct linux_binfmt * fmt;
@@ -237,13 +236,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos,
237 236
238static int __bprm_mm_init(struct linux_binprm *bprm) 237static int __bprm_mm_init(struct linux_binprm *bprm)
239{ 238{
240 int err = -ENOMEM; 239 int err;
241 struct vm_area_struct *vma = NULL; 240 struct vm_area_struct *vma = NULL;
242 struct mm_struct *mm = bprm->mm; 241 struct mm_struct *mm = bprm->mm;
243 242
244 bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 243 bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
245 if (!vma) 244 if (!vma)
246 goto err; 245 return -ENOMEM;
247 246
248 down_write(&mm->mmap_sem); 247 down_write(&mm->mmap_sem);
249 vma->vm_mm = mm; 248 vma->vm_mm = mm;
@@ -256,28 +255,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
256 */ 255 */
257 vma->vm_end = STACK_TOP_MAX; 256 vma->vm_end = STACK_TOP_MAX;
258 vma->vm_start = vma->vm_end - PAGE_SIZE; 257 vma->vm_start = vma->vm_end - PAGE_SIZE;
259
260 vma->vm_flags = VM_STACK_FLAGS; 258 vma->vm_flags = VM_STACK_FLAGS;
261 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 259 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
262 err = insert_vm_struct(mm, vma); 260 err = insert_vm_struct(mm, vma);
263 if (err) { 261 if (err)
264 up_write(&mm->mmap_sem);
265 goto err; 262 goto err;
266 }
267 263
268 mm->stack_vm = mm->total_vm = 1; 264 mm->stack_vm = mm->total_vm = 1;
269 up_write(&mm->mmap_sem); 265 up_write(&mm->mmap_sem);
270
271 bprm->p = vma->vm_end - sizeof(void *); 266 bprm->p = vma->vm_end - sizeof(void *);
272
273 return 0; 267 return 0;
274
275err: 268err:
276 if (vma) { 269 up_write(&mm->mmap_sem);
277 bprm->vma = NULL; 270 bprm->vma = NULL;
278 kmem_cache_free(vm_area_cachep, vma); 271 kmem_cache_free(vm_area_cachep, vma);
279 }
280
281 return err; 272 return err;
282} 273}
283 274
@@ -684,7 +675,7 @@ struct file *open_exec(const char *name)
684 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 675 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
685 goto out_path_put; 676 goto out_path_put;
686 677
687 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); 678 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
688 if (err) 679 if (err)
689 goto out_path_put; 680 goto out_path_put;
690 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN); 681 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
@@ -695,6 +686,8 @@ struct file *open_exec(const char *name)
695 if (IS_ERR(file)) 686 if (IS_ERR(file))
696 return file; 687 return file;
697 688
689 fsnotify_open(file->f_path.dentry);
690
698 err = deny_write_access(file); 691 err = deny_write_access(file);
699 if (err) { 692 if (err) {
700 fput(file); 693 fput(file);
@@ -1178,41 +1171,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1178 unsigned int depth = bprm->recursion_depth; 1171 unsigned int depth = bprm->recursion_depth;
1179 int try,retval; 1172 int try,retval;
1180 struct linux_binfmt *fmt; 1173 struct linux_binfmt *fmt;
1181#ifdef __alpha__
1182 /* handle /sbin/loader.. */
1183 {
1184 struct exec * eh = (struct exec *) bprm->buf;
1185
1186 if (!bprm->loader && eh->fh.f_magic == 0x183 &&
1187 (eh->fh.f_flags & 0x3000) == 0x3000)
1188 {
1189 struct file * file;
1190 unsigned long loader;
1191 1174
1192 allow_write_access(bprm->file);
1193 fput(bprm->file);
1194 bprm->file = NULL;
1195
1196 loader = bprm->vma->vm_end - sizeof(void *);
1197
1198 file = open_exec("/sbin/loader");
1199 retval = PTR_ERR(file);
1200 if (IS_ERR(file))
1201 return retval;
1202
1203 /* Remember if the application is TASO. */
1204 bprm->taso = eh->ah.entry < 0x100000000UL;
1205
1206 bprm->file = file;
1207 bprm->loader = loader;
1208 retval = prepare_binprm(bprm);
1209 if (retval<0)
1210 return retval;
1211 /* should call search_binary_handler recursively here,
1212 but it does not matter */
1213 }
1214 }
1215#endif
1216 retval = security_bprm_check(bprm); 1175 retval = security_bprm_check(bprm);
1217 if (retval) 1176 if (retval)
1218 return retval; 1177 return retval;
@@ -1737,7 +1696,7 @@ int get_dumpable(struct mm_struct *mm)
1737 return (ret >= 2) ? 2 : ret; 1696 return (ret >= 2) ? 2 : ret;
1738} 1697}
1739 1698
1740int do_coredump(long signr, int exit_code, struct pt_regs * regs) 1699void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1741{ 1700{
1742 struct core_state core_state; 1701 struct core_state core_state;
1743 char corename[CORENAME_MAX_SIZE + 1]; 1702 char corename[CORENAME_MAX_SIZE + 1];
@@ -1821,6 +1780,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1821 1780
1822 if (ispipe) { 1781 if (ispipe) {
1823 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); 1782 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
1783 if (!helper_argv) {
1784 printk(KERN_WARNING "%s failed to allocate memory\n",
1785 __func__);
1786 goto fail_unlock;
1787 }
1824 /* Terminate the string before the first option */ 1788 /* Terminate the string before the first option */
1825 delimit = strchr(corename, ' '); 1789 delimit = strchr(corename, ' ');
1826 if (delimit) 1790 if (delimit)
@@ -1888,5 +1852,5 @@ fail_unlock:
1888 put_cred(cred); 1852 put_cred(cred);
1889 coredump_finish(mm); 1853 coredump_finish(mm);
1890fail: 1854fail:
1891 return retval; 1855 return;
1892} 1856}