diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-06 17:12:33 +0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 12:57:07 +0400 |
commit | bc77daa783afcc56004d4ed3582983b234e01872 (patch) | |
tree | 9bd21739d43b5193eebaff2ed04de5113844a0f8 | |
parent | 0888c321de70d93f8e15614073af6c3ef56088b1 (diff) | |
download | linux-bc77daa783afcc56004d4ed3582983b234e01872.tar.xz |
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>
-rw-r--r-- | fs/namei.c | 24 |
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, nd->flags &= ~LOOKUP_PARENT; nd->flags |= op->intent; - switch (nd->last_type) { - case LAST_DOTDOT: - case LAST_DOT: + if (nd->last_type != LAST_NORM) { error = handle_dots(nd, nd->last_type); if (error) return error; - /* fallthrough */ - case LAST_ROOT: - error = complete_walk(nd); - if (error) - return error; - audit_inode(name, nd->path.dentry, 0); - if (open_flag & O_CREAT) { - error = -EISDIR; - goto out; - } - goto finish_open; - case LAST_BIND: - error = complete_walk(nd); - if (error) - return error; - audit_inode(name, dir, 0); goto finish_open; } @@ -2841,19 +2823,19 @@ finish_lookup: } nd->inode = inode; /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ +finish_open: error = complete_walk(nd); if (error) { path_put(&save_parent); return error; } + audit_inode(name, nd->path.dentry, 0); error = -EISDIR; if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) goto out; error = -ENOTDIR; if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) goto out; - audit_inode(name, nd->path.dentry, 0); -finish_open: if (!S_ISREG(nd->inode->i_mode)) will_truncate = false; |