aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@www.linux.org.uk>2005-06-06 16:36:11 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-06 17:42:27 -0400
commitd9d29a29669f96903d9950bb881c2a393fd33849 (patch)
treed2e12822db98a1bf8feac9f428ba18d867771a85 /fs/namei.c
parent4b7b9772e4c3d87e649d4c419d2487aacf1235aa (diff)
[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>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 411bb3243c36..6a884682b0a7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -544,15 +544,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
544 current->total_link_count++; 544 current->total_link_count++;
545 nd->depth++; 545 nd->depth++;
546 if (path->mnt != nd->mnt) 546 if (path->mnt != nd->mnt)
547 mntput(nd->mnt); 547 mntput(path->mnt);
548 err = __do_follow_link(path, nd); 548 err = __do_follow_link(path, nd);
549 current->link_count--; 549 current->link_count--;
550 nd->depth--; 550 nd->depth--;
551 return err; 551 return err;
552loop: 552loop:
553 if (path->mnt != nd->mnt)
554 mntput(nd->mnt);
555 dput(path->dentry); 553 dput(path->dentry);
554 if (path->mnt != nd->mnt)
555 mntput(path->mnt);
556 path_release(nd); 556 path_release(nd);
557 return err; 557 return err;
558} 558}
@@ -906,7 +906,7 @@ return_base:
906out_dput: 906out_dput:
907 dput(next.dentry); 907 dput(next.dentry);
908 if (nd->mnt != next.mnt) 908 if (nd->mnt != next.mnt)
909 mntput(nd->mnt); 909 mntput(next.mnt);
910 break; 910 break;
911 } 911 }
912 path_release(nd); 912 path_release(nd);
@@ -1551,8 +1551,7 @@ do_link:
1551 if (error) 1551 if (error)
1552 goto exit_dput; 1552 goto exit_dput;
1553 if (nd->mnt != path.mnt) 1553 if (nd->mnt != path.mnt)
1554 mntput(nd->mnt); 1554 mntput(path.mnt);
1555 nd->mnt = path.mnt;
1556 error = __do_follow_link(&path, nd); 1555 error = __do_follow_link(&path, nd);
1557 if (error) 1556 if (error)
1558 return error; 1557 return error;