mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
[PATCH] namei fixes (15/19)
Getting rid of sloppy logics: a) in do_follow_link() we have the wrong vfsmount dropped if our symlink had been mounted on something. Currently it worls only because we never get such situation (modulo filesystem playing dirty tricks on us). And it obfuscates already convoluted logics... b) same goes for open_namei(). c) in __link_path_walk() we have another "it should never happen" sloppiness - out_dput: there does double-free on underlying vfsmount and leaks the covering one if we hit it just after crossing a mountpoint. Again, wrong vfsmount getting dropped. d) another too-early-mntput() race - in do_follow_mount() we need to postpone conditional mntput(path->mnt) until after dput(path->dentry). Again, this one happens only in it-currently-never-happens-unless-some-fs-plays-dirty scenario... Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
4b7b9772e4
commit
d9d29a2966
1 changed files with 5 additions and 6 deletions
11
fs/namei.c
11
fs/namei.c
|
@ -544,15 +544,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
|
|||
current->total_link_count++;
|
||||
nd->depth++;
|
||||
if (path->mnt != nd->mnt)
|
||||
mntput(nd->mnt);
|
||||
mntput(path->mnt);
|
||||
err = __do_follow_link(path, nd);
|
||||
current->link_count--;
|
||||
nd->depth--;
|
||||
return err;
|
||||
loop:
|
||||
if (path->mnt != nd->mnt)
|
||||
mntput(nd->mnt);
|
||||
dput(path->dentry);
|
||||
if (path->mnt != nd->mnt)
|
||||
mntput(path->mnt);
|
||||
path_release(nd);
|
||||
return err;
|
||||
}
|
||||
|
@ -906,7 +906,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
|
|||
out_dput:
|
||||
dput(next.dentry);
|
||||
if (nd->mnt != next.mnt)
|
||||
mntput(nd->mnt);
|
||||
mntput(next.mnt);
|
||||
break;
|
||||
}
|
||||
path_release(nd);
|
||||
|
@ -1551,8 +1551,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
|
|||
if (error)
|
||||
goto exit_dput;
|
||||
if (nd->mnt != path.mnt)
|
||||
mntput(nd->mnt);
|
||||
nd->mnt = path.mnt;
|
||||
mntput(path.mnt);
|
||||
error = __do_follow_link(&path, nd);
|
||||
if (error)
|
||||
return error;
|
||||
|
|
Loading…
Reference in a new issue