aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/fs/exec.c b/fs/exec.c
index b8792a131533..9696bbf0f0b1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -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,