summaryrefslogtreecommitdiff
path: root/fs/nfs/callback_xdr.c
diff options
context:
space:
mode:
authorOlga Kornievskaia <kolga@netapp.com>2018-07-26 23:04:47 +0300
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-07-31 19:53:40 +0300
commit32cd3ee511f4e07ca25d71163b50e704808d22f4 (patch)
tree2ae66a7cf7faf3fbd3157e08dcf86aad79aee9da /fs/nfs/callback_xdr.c
parent1a54c0cfcbb2d93b6c057b633984f0fd8b882555 (diff)
downloadlinux-32cd3ee511f4e07ca25d71163b50e704808d22f4.tar.xz
NFSv4.0 fix client reference leak in callback
If there is an error during processing of a callback message, it leads to refrence leak on the client structure and eventually an unclean superblock. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/callback_xdr.c')
-rw-r--r--fs/nfs/callback_xdr.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index a813979b5be0..cb905c0e606c 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -883,16 +883,21 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
if (hdr_arg.minorversion == 0) {
cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
- if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
+ if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) {
+ if (cps.clp)
+ nfs_put_client(cps.clp);
goto out_invalidcred;
+ }
}
cps.minorversion = hdr_arg.minorversion;
hdr_res.taglen = hdr_arg.taglen;
hdr_res.tag = hdr_arg.tag;
- if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
+ if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) {
+ if (cps.clp)
+ nfs_put_client(cps.clp);
return rpc_system_err;
-
+ }
while (status == 0 && nops != hdr_arg.nops) {
status = process_op(nops, rqstp, &xdr_in,
rqstp->rq_argp, &xdr_out, rqstp->rq_resp,