提交 d9d29a29 编写于 作者: A Al Viro 提交者: Linus Torvalds

[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: NAl Viro <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 4b7b9772
...@@ -544,15 +544,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) ...@@ -544,15 +544,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
current->total_link_count++; current->total_link_count++;
nd->depth++; nd->depth++;
if (path->mnt != nd->mnt) if (path->mnt != nd->mnt)
mntput(nd->mnt); mntput(path->mnt);
err = __do_follow_link(path, nd); err = __do_follow_link(path, nd);
current->link_count--; current->link_count--;
nd->depth--; nd->depth--;
return err; return err;
loop: loop:
if (path->mnt != nd->mnt)
mntput(nd->mnt);
dput(path->dentry); dput(path->dentry);
if (path->mnt != nd->mnt)
mntput(path->mnt);
path_release(nd); path_release(nd);
return err; return err;
} }
...@@ -906,7 +906,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) ...@@ -906,7 +906,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
out_dput: out_dput:
dput(next.dentry); dput(next.dentry);
if (nd->mnt != next.mnt) if (nd->mnt != next.mnt)
mntput(nd->mnt); mntput(next.mnt);
break; break;
} }
path_release(nd); path_release(nd);
...@@ -1551,8 +1551,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) ...@@ -1551,8 +1551,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
if (error) if (error)
goto exit_dput; goto exit_dput;
if (nd->mnt != path.mnt) if (nd->mnt != path.mnt)
mntput(nd->mnt); mntput(path.mnt);
nd->mnt = path.mnt;
error = __do_follow_link(&path, nd); error = __do_follow_link(&path, nd);
if (error) if (error)
return error; return error;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册