NFSd: Fix filehandle leak in exp_pseudoroot() and nfsd4_path()
nfsd4_path() allocates a temporary filehandle and then fails to free it before the function exits, leaking reference counts to the dentry and export that it refers to. Also, nfsd4_lookupp() puts the result of exp_pseudoroot() in a temporary filehandle which it releases on success of exp_pseudoroot() but not on failure; fix exp_pseudoroot to ensure that on failure it releases the filehandle before returning. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
bc6c53d5a1
commit
2671a4bf35
@ -1341,6 +1341,8 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
|||||||
if (rv)
|
if (rv)
|
||||||
goto out;
|
goto out;
|
||||||
rv = check_nfsd_access(exp, rqstp);
|
rv = check_nfsd_access(exp, rqstp);
|
||||||
|
if (rv)
|
||||||
|
fh_put(fhp);
|
||||||
out:
|
out:
|
||||||
exp_put(exp);
|
exp_put(exp);
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1599,7 +1599,8 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
|
|||||||
static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
|
static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
|
||||||
{
|
{
|
||||||
struct svc_fh tmp_fh;
|
struct svc_fh tmp_fh;
|
||||||
char *path, *rootpath;
|
char *path = NULL, *rootpath;
|
||||||
|
size_t rootlen;
|
||||||
|
|
||||||
fh_init(&tmp_fh, NFS4_FHSIZE);
|
fh_init(&tmp_fh, NFS4_FHSIZE);
|
||||||
*stat = exp_pseudoroot(rqstp, &tmp_fh);
|
*stat = exp_pseudoroot(rqstp, &tmp_fh);
|
||||||
@ -1609,14 +1610,18 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *
|
|||||||
|
|
||||||
path = exp->ex_pathname;
|
path = exp->ex_pathname;
|
||||||
|
|
||||||
if (strncmp(path, rootpath, strlen(rootpath))) {
|
rootlen = strlen(rootpath);
|
||||||
|
if (strncmp(path, rootpath, rootlen)) {
|
||||||
dprintk("nfsd: fs_locations failed;"
|
dprintk("nfsd: fs_locations failed;"
|
||||||
"%s is not contained in %s\n", path, rootpath);
|
"%s is not contained in %s\n", path, rootpath);
|
||||||
*stat = nfserr_notsupp;
|
*stat = nfserr_notsupp;
|
||||||
return NULL;
|
path = NULL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
path += rootlen;
|
||||||
return path + strlen(rootpath);
|
out:
|
||||||
|
fh_put(&tmp_fh);
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user