mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 21:33:00 +00:00
rcu pathwalk: prevent bogus hard errors from may_lookup()
If lazy call of ->permission() returns a hard error, check that try_to_unlazy() succeeds before returning it. That both makes life easier for ->permission() instances and closes the race in ENOTDIR handling - it is possible that positive d_can_lookup() seen in link_path_walk() applies to the state *after* unlink() + mkdir(), while nd->inode matches the state prior to that. Normally seeing e.g. EACCES from permission check in rcu pathwalk means that with some timings non-rcu pathwalk would've run into the same; however, running into a non-executable regular file in the middle of a pathname would not get to permission check - it would fail with ENOTDIR instead. Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
583340de1d
commit
cdb67fdeed
@ -1717,7 +1717,11 @@ static inline int may_lookup(struct mnt_idmap *idmap,
|
||||
{
|
||||
if (nd->flags & LOOKUP_RCU) {
|
||||
int err = inode_permission(idmap, nd->inode, MAY_EXEC|MAY_NOT_BLOCK);
|
||||
if (err != -ECHILD || !try_to_unlazy(nd))
|
||||
if (!err) // success, keep going
|
||||
return 0;
|
||||
if (!try_to_unlazy(nd))
|
||||
return -ECHILD; // redo it all non-lazy
|
||||
if (err != -ECHILD) // hard error
|
||||
return err;
|
||||
}
|
||||
return inode_permission(idmap, nd->inode, MAY_EXEC);
|
||||
|
Loading…
Reference in New Issue
Block a user