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>
This commit is contained in:
Родитель
0888c321de
Коммит
bc77daa783
24
fs/namei.c
24
fs/namei.c
|
@ -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 @@ finish_lookup:
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче