mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
nfsd: fix refcount leak in nfsd_set_fh_dentry()
nfsd exports a "pseudo root filesystem" which is used by NFSv4 to find
the various exported filesystems using LOOKUP requests from a known root
filehandle. NFSv3 uses the MOUNT protocol to find those exported
filesystems and so is not given access to the pseudo root filesystem.
If a v3 (or v2) client uses a filehandle from that filesystem,
nfsd_set_fh_dentry() will report an error, but still stores the export
in "struct svc_fh" even though it also drops the reference (exp_put()).
This means that when fh_put() is called an extra reference will be dropped
which can lead to use-after-free and possible denial of service.
Normal NFS usage will not provide a pseudo-root filehandle to a v3
client. This bug can only be triggered by the client synthesising an
incorrect filehandle.
To fix this we move the assignments to the svc_fh later, after all
possible error cases have been detected.
Reported-and-tested-by: tianshuo han <hantianshuo233@gmail.com>
Fixes: ef7f6c4904 ("nfsd: move V4ROOT version check to nfsd_set_fh_dentry()")
Signed-off-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
3e7f011c25
commit
8a7348a9ed
|
|
@ -269,9 +269,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net,
|
|||
dentry);
|
||||
}
|
||||
|
||||
fhp->fh_dentry = dentry;
|
||||
fhp->fh_export = exp;
|
||||
|
||||
switch (fhp->fh_maxsize) {
|
||||
case NFS4_FHSIZE:
|
||||
if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR)
|
||||
|
|
@ -293,6 +290,9 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net,
|
|||
goto out;
|
||||
}
|
||||
|
||||
fhp->fh_dentry = dentry;
|
||||
fhp->fh_export = exp;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
exp_put(exp);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user