Commit bc77daa7 authored by Al Viro's avatar Al Viro

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 0888c321
...@@ -2690,28 +2690,10 @@ static int do_last(struct nameidata *nd, struct path *path, ...@@ -2690,28 +2690,10 @@ static int do_last(struct nameidata *nd, struct path *path,
nd->flags &= ~LOOKUP_PARENT; nd->flags &= ~LOOKUP_PARENT;
nd->flags |= op->intent; nd->flags |= op->intent;
switch (nd->last_type) { if (nd->last_type != LAST_NORM) {
case LAST_DOTDOT:
case LAST_DOT:
error = handle_dots(nd, nd->last_type); error = handle_dots(nd, nd->last_type);
if (error) if (error)
return 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; goto finish_open;
} }
...@@ -2841,19 +2823,19 @@ static int do_last(struct nameidata *nd, struct path *path, ...@@ -2841,19 +2823,19 @@ static int do_last(struct nameidata *nd, struct path *path,
} }
nd->inode = inode; nd->inode = inode;
/* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */
finish_open:
error = complete_walk(nd); error = complete_walk(nd);
if (error) { if (error) {
path_put(&save_parent); path_put(&save_parent);
return error; return error;
} }
audit_inode(name, nd->path.dentry, 0);
error = -EISDIR; error = -EISDIR;
if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
goto out; goto out;
error = -ENOTDIR; error = -ENOTDIR;
if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
goto out; goto out;
audit_inode(name, nd->path.dentry, 0);
finish_open:
if (!S_ISREG(nd->inode->i_mode)) if (!S_ISREG(nd->inode->i_mode))
will_truncate = false; will_truncate = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment