diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-04-18 02:32:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-04-20 23:01:15 -0400 |
commit | 1644ccc8a99ae73859c39372f96afdbf03c9f80d (patch) | |
tree | 27b568d2fcc00738a505fd562d7fa4728aa43d7f /fs | |
parent | e5d67f0715bc60f6c19abdd86d007d7bb29c9951 (diff) | |
download | op-kernel-dev-1644ccc8a99ae73859c39372f96afdbf03c9f80d.zip op-kernel-dev-1644ccc8a99ae73859c39372f96afdbf03c9f80d.tar.gz |
Safer nfsd_cross_mnt()
AFAICS, we have a subtle bug there: if we have crossed mountpoint
*and* it got mount --move'd away, we'll be holding only one
reference to fs containing dentry - exp->ex_path.mnt. IOW, we
ought to dput() before exp_put().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/vfs.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index ab93fcf..46e6bd2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -116,10 +116,15 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, } if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { /* successfully crossed mount point */ - exp_put(exp); - *expp = exp2; + /* + * This is subtle: dentry is *not* under mnt at this point. + * The only reason we are safe is that original mnt is pinned + * down by exp, so we should dput before putting exp. + */ dput(dentry); *dpp = mounts; + exp_put(exp); + *expp = exp2; } else { exp_put(exp2); dput(mounts); |