diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 58 |
1 files changed, 30 insertions, 28 deletions
@@ -656,38 +656,40 @@ EXPORT_SYMBOL(setup_arg_pages); | |||
656 | struct file *open_exec(const char *name) | 656 | struct file *open_exec(const char *name) |
657 | { | 657 | { |
658 | struct nameidata nd; | 658 | struct nameidata nd; |
659 | int err; | ||
660 | struct file *file; | 659 | struct file *file; |
660 | int err; | ||
661 | 661 | ||
662 | err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); | 662 | err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, |
663 | file = ERR_PTR(err); | 663 | FMODE_READ|FMODE_EXEC); |
664 | 664 | if (err) | |
665 | if (!err) { | 665 | goto out; |
666 | struct inode *inode = nd.path.dentry->d_inode; | 666 | |
667 | file = ERR_PTR(-EACCES); | 667 | err = -EACCES; |
668 | if (S_ISREG(inode->i_mode)) { | 668 | if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) |
669 | int err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); | 669 | goto out_path_put; |
670 | file = ERR_PTR(err); | 670 | |
671 | if (!err) { | 671 | err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); |
672 | file = nameidata_to_filp(&nd, | 672 | if (err) |
673 | O_RDONLY|O_LARGEFILE); | 673 | goto out_path_put; |
674 | if (!IS_ERR(file)) { | 674 | |
675 | err = deny_write_access(file); | 675 | file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); |
676 | if (err) { | 676 | if (IS_ERR(file)) |
677 | fput(file); | 677 | return file; |
678 | file = ERR_PTR(err); | 678 | |
679 | } | 679 | err = deny_write_access(file); |
680 | } | 680 | if (err) { |
681 | out: | 681 | fput(file); |
682 | return file; | 682 | goto out; |
683 | } | ||
684 | } | ||
685 | release_open_intent(&nd); | ||
686 | path_put(&nd.path); | ||
687 | } | 683 | } |
688 | goto out; | ||
689 | } | ||
690 | 684 | ||
685 | return file; | ||
686 | |||
687 | out_path_put: | ||
688 | release_open_intent(&nd); | ||
689 | path_put(&nd.path); | ||
690 | out: | ||
691 | return ERR_PTR(err); | ||
692 | } | ||
691 | EXPORT_SYMBOL(open_exec); | 693 | EXPORT_SYMBOL(open_exec); |
692 | 694 | ||
693 | int kernel_read(struct file *file, unsigned long offset, | 695 | int kernel_read(struct file *file, unsigned long offset, |