aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-06-06 09:12:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:07 -0400
commitbc77daa783afcc56004d4ed3582983b234e01872 (patch)
tree9bd21739d43b5193eebaff2ed04de5113844a0f8 /fs/namei.c
parent0888c321de70d93f8e15614073af6c3ef56088b1 (diff)
do_last(): fix missing checks for LAST_BIND case
/proc/self/cwd with O_CREAT should fail with EISDIR. /proc/self/exe, OTOH, should fail with ENOTDIR when opened with O_DIRECTORY. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c24
1 files changed, 3 insertions, 21 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 9ed9361223c0..1bc7b7582a66 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2690,28 +2690,10 @@ static int do_last(struct nameidata *nd, struct path *path,
2690 nd->flags &= ~LOOKUP_PARENT; 2690 nd->flags &= ~LOOKUP_PARENT;
2691 nd->flags |= op->intent; 2691 nd->flags |= op->intent;
2692 2692
2693 switch (nd->last_type) { 2693 if (nd->last_type != LAST_NORM) {
2694 case LAST_DOTDOT:
2695 case LAST_DOT:
2696 error = handle_dots(nd, nd->last_type); 2694 error = handle_dots(nd, nd->last_type);
2697 if (error) 2695 if (error)
2698 return error; 2696 return error;
2699 /* fallthrough */
2700 case LAST_ROOT:
2701 error = complete_walk(nd);
2702 if (error)
2703 return error;
2704 audit_inode(name, nd->path.dentry, 0);
2705 if (open_flag & O_CREAT) {
2706 error = -EISDIR;
2707 goto out;
2708 }
2709 goto finish_open;
2710 case LAST_BIND:
2711 error = complete_walk(nd);
2712 if (error)
2713 return error;
2714 audit_inode(name, dir, 0);
2715 goto finish_open; 2697 goto finish_open;
2716 } 2698 }
2717 2699
@@ -2841,19 +2823,19 @@ finish_lookup:
2841 } 2823 }
2842 nd->inode = inode; 2824 nd->inode = inode;
2843 /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ 2825 /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */
2826finish_open:
2844 error = complete_walk(nd); 2827 error = complete_walk(nd);
2845 if (error) { 2828 if (error) {
2846 path_put(&save_parent); 2829 path_put(&save_parent);
2847 return error; 2830 return error;
2848 } 2831 }
2832 audit_inode(name, nd->path.dentry, 0);
2849 error = -EISDIR; 2833 error = -EISDIR;
2850 if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) 2834 if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
2851 goto out; 2835 goto out;
2852 error = -ENOTDIR; 2836 error = -ENOTDIR;
2853 if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) 2837 if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
2854 goto out; 2838 goto out;
2855 audit_inode(name, nd->path.dentry, 0);
2856finish_open:
2857 if (!S_ISREG(nd->inode->i_mode)) 2839 if (!S_ISREG(nd->inode->i_mode))
2858 will_truncate = false; 2840 will_truncate = false;
2859 2841