aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-28 15:14:43 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-28 15:14:43 -0400
commit414f746d232d41ed6ae8632c4495ae795373c44b (patch)
tree167f9bc8f139c6e82e6732b38c7a938b8a9d31cd /fs/exec.c
parent5a7a201c51c324876d00a54e7208af6af12d1ca4 (diff)
parentc9272c4f9fbe2087beb3392f526dc5b19efaa56b (diff)
Merge branch 'linus' into cpus4096
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c93
1 files changed, 52 insertions, 41 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 5e559013e303..9696bbf0f0b1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -42,13 +42,13 @@
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/namei.h> 43#include <linux/namei.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/ptrace.h>
46#include <linux/mount.h> 45#include <linux/mount.h>
47#include <linux/security.h> 46#include <linux/security.h>
48#include <linux/syscalls.h> 47#include <linux/syscalls.h>
49#include <linux/tsacct_kern.h> 48#include <linux/tsacct_kern.h>
50#include <linux/cn_proc.h> 49#include <linux/cn_proc.h>
51#include <linux/audit.h> 50#include <linux/audit.h>
51#include <linux/tracehook.h>
52 52
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54#include <asm/mmu_context.h> 54#include <asm/mmu_context.h>
@@ -106,11 +106,17 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
106 */ 106 */
107asmlinkage long sys_uselib(const char __user * library) 107asmlinkage long sys_uselib(const char __user * library)
108{ 108{
109 struct file * file; 109 struct file *file;
110 struct nameidata nd; 110 struct nameidata nd;
111 int error; 111 char *tmp = getname(library);
112 112 int error = PTR_ERR(tmp);
113 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); 113
114 if (!IS_ERR(tmp)) {
115 error = path_lookup_open(AT_FDCWD, tmp,
116 LOOKUP_FOLLOW, &nd,
117 FMODE_READ|FMODE_EXEC);
118 putname(tmp);
119 }
114 if (error) 120 if (error)
115 goto out; 121 goto out;
116 122
@@ -118,7 +124,11 @@ asmlinkage long sys_uselib(const char __user * library)
118 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 124 if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
119 goto exit; 125 goto exit;
120 126
121 error = vfs_permission(&nd, MAY_READ | MAY_EXEC); 127 error = -EACCES;
128 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
129 goto exit;
130
131 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
122 if (error) 132 if (error)
123 goto exit; 133 goto exit;
124 134
@@ -656,38 +666,43 @@ EXPORT_SYMBOL(setup_arg_pages);
656struct file *open_exec(const char *name) 666struct file *open_exec(const char *name)
657{ 667{
658 struct nameidata nd; 668 struct nameidata nd;
659 int err;
660 struct file *file; 669 struct file *file;
670 int err;
661 671
662 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); 672 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
663 file = ERR_PTR(err); 673 FMODE_READ|FMODE_EXEC);
664 674 if (err)
665 if (!err) { 675 goto out;
666 struct inode *inode = nd.path.dentry->d_inode; 676
667 file = ERR_PTR(-EACCES); 677 err = -EACCES;
668 if (S_ISREG(inode->i_mode)) { 678 if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
669 int err = vfs_permission(&nd, MAY_EXEC); 679 goto out_path_put;
670 file = ERR_PTR(err); 680
671 if (!err) { 681 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
672 file = nameidata_to_filp(&nd, 682 goto out_path_put;
673 O_RDONLY|O_LARGEFILE); 683
674 if (!IS_ERR(file)) { 684 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
675 err = deny_write_access(file); 685 if (err)
676 if (err) { 686 goto out_path_put;
677 fput(file); 687
678 file = ERR_PTR(err); 688 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
679 } 689 if (IS_ERR(file))
680 } 690 return file;
681out: 691
682 return file; 692 err = deny_write_access(file);
683 } 693 if (err) {
684 } 694 fput(file);
685 release_open_intent(&nd); 695 goto out;
686 path_put(&nd.path);
687 } 696 }
688 goto out;
689}
690 697
698 return file;
699
700 out_path_put:
701 release_open_intent(&nd);
702 path_put(&nd.path);
703 out:
704 return ERR_PTR(err);
705}
691EXPORT_SYMBOL(open_exec); 706EXPORT_SYMBOL(open_exec);
692 707
693int kernel_read(struct file *file, unsigned long offset, 708int kernel_read(struct file *file, unsigned long offset,
@@ -1071,13 +1086,8 @@ EXPORT_SYMBOL(prepare_binprm);
1071 1086
1072static int unsafe_exec(struct task_struct *p) 1087static int unsafe_exec(struct task_struct *p)
1073{ 1088{
1074 int unsafe = 0; 1089 int unsafe = tracehook_unsafe_exec(p);
1075 if (p->ptrace & PT_PTRACED) { 1090
1076 if (p->ptrace & PT_PTRACE_CAP)
1077 unsafe |= LSM_UNSAFE_PTRACE_CAP;
1078 else
1079 unsafe |= LSM_UNSAFE_PTRACE;
1080 }
1081 if (atomic_read(&p->fs->count) > 1 || 1091 if (atomic_read(&p->fs->count) > 1 ||
1082 atomic_read(&p->files->count) > 1 || 1092 atomic_read(&p->files->count) > 1 ||
1083 atomic_read(&p->sighand->count) > 1) 1093 atomic_read(&p->sighand->count) > 1)
@@ -1214,6 +1224,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1214 read_unlock(&binfmt_lock); 1224 read_unlock(&binfmt_lock);
1215 retval = fn(bprm, regs); 1225 retval = fn(bprm, regs);
1216 if (retval >= 0) { 1226 if (retval >= 0) {
1227 tracehook_report_exec(fmt, bprm, regs);
1217 put_binfmt(fmt); 1228 put_binfmt(fmt);
1218 allow_write_access(bprm->file); 1229 allow_write_access(bprm->file);
1219 if (bprm->file) 1230 if (bprm->file)