21ab4e
From 61059a12fa6dd06a764a9d030bc2d294e4000ddb Mon Sep 17 00:00:00 2001
21ab4e
From: Niels de Vos <ndevos@redhat.com>
21ab4e
Date: Mon, 3 Jul 2017 16:24:53 +0200
21ab4e
Subject: [PATCH 549/557] nfs/nlm: use refcounting for nfs3_call_state_t
21ab4e
21ab4e
In order to track down a potential use-after-free of the
21ab4e
nfs3_call_state_t structure in the NLM component, add reference counting
21ab4e
where teh structure is used. This should prevent premature free'ing of
21ab4e
the structure.
21ab4e
21ab4e
Cherry picked from commit 01bfdd4d1759423681d311da33f4ac2346ace445:
21ab4e
> Change-Id: Ib1f13b0463ab1e012b7b49a623c91f0f3e73e1fb
21ab4e
> BUG: 1467313
21ab4e
> Signed-off-by: Niels de Vos <ndevos@redhat.com>
21ab4e
> Reviewed-on: https://review.gluster.org/17699
21ab4e
> Reviewed-by: jiffin tony Thottan <jthottan@redhat.com>
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
21ab4e
Change-Id: Ib1f13b0463ab1e012b7b49a623c91f0f3e73e1fb
21ab4e
BUG: 1411344
21ab4e
Signed-off-by: Niels de Vos <ndevos@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/111768
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 xlators/nfs/server/src/nlm4.c | 46 ++++++++++++++++++++++++++++++++-----------
21ab4e
 1 file changed, 35 insertions(+), 11 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c
21ab4e
index ea4e628..d678edc 100644
21ab4e
--- a/xlators/nfs/server/src/nlm4.c
21ab4e
+++ b/xlators/nfs/server/src/nlm4.c
21ab4e
@@ -532,8 +532,11 @@ nlm4_file_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                 fd_bind (cs->fd);
21ab4e
         cs->resolve_ret = op_ret;
21ab4e
         cs->resume_fn (cs);
21ab4e
+
21ab4e
         frame->local = NULL;
21ab4e
         STACK_DESTROY (frame->root);
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return 0;
21ab4e
 }
21ab4e
 
21ab4e
@@ -673,7 +676,7 @@ nlm4_file_open_and_resume(nfs3_call_state_t *cs, nlm4_resume_fn_t resume)
21ab4e
         frame->root->pid = NFS_PID;
21ab4e
         frame->root->uid = rpcsvc_request_uid (cs->req);
21ab4e
         frame->root->gid = rpcsvc_request_gid (cs->req);
21ab4e
-        frame->local = cs;
21ab4e
+        frame->local = GF_REF_GET (cs);
21ab4e
         nfs_fix_groups (cs->nfsx, frame->root);
21ab4e
 
21ab4e
         STACK_WIND_COOKIE (frame, nlm4_file_open_cbk, cs->vol, cs->vol,
21ab4e
@@ -810,7 +813,7 @@ nlm4_test_fd_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nfs_request_user_init (&nfu, cs->req);
21ab4e
         nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_testargs.alock,
21ab4e
                                cs->args.nlm4_testargs.exclusive);
21ab4e
@@ -818,6 +821,8 @@ nlm4_test_fd_resume (void *carg)
21ab4e
         ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_GETLK, &flock,
21ab4e
                       nlm4svc_test_cbk, cs);
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -833,7 +838,7 @@ nlm4_test_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nlm4_check_fh_resolve_status (cs, stat, nlm4err);
21ab4e
         fd = fd_anonymous (cs->resolvedloc.inode);
21ab4e
         if (!fd)
21ab4e
@@ -850,6 +855,8 @@ nlm4err:
21ab4e
                 nfs3_call_state_wipe (cs);
21ab4e
         }
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1375,7 +1382,7 @@ nlm4_lock_fd_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nlm4_check_fh_resolve_status (cs, stat, nlm4err);
21ab4e
         (void) nlm_search_and_add (cs->fd,
21ab4e
                                    cs->args.nlm4_lockargs.alock.caller_name);
21ab4e
@@ -1406,6 +1413,8 @@ nlm4err:
21ab4e
                 nfs3_call_state_wipe (cs);
21ab4e
         }
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1420,7 +1429,7 @@ nlm4_lock_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nlm4_check_fh_resolve_status (cs, stat, nlm4err);
21ab4e
         ret = nlm4_file_open_and_resume (cs, nlm4_lock_fd_resume);
21ab4e
 
21ab4e
@@ -1434,6 +1443,8 @@ nlm4err:
21ab4e
                 nfs3_call_state_wipe (cs);
21ab4e
         }
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1553,7 +1564,7 @@ nlm4_cancel_fd_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nfs_request_user_init (&nfu, cs->req);
21ab4e
         nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_cancargs.alock,
21ab4e
                                 cs->args.nlm4_cancargs.exclusive);
21ab4e
@@ -1562,6 +1573,8 @@ nlm4_cancel_fd_resume (void *carg)
21ab4e
         ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLK,
21ab4e
                       &flock, nlm4svc_cancel_cbk, cs);
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1576,7 +1589,7 @@ nlm4_cancel_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nlm4_check_fh_resolve_status (cs, stat, nlm4err);
21ab4e
 
21ab4e
         nlmclnt = nlm_get_uniq (cs->args.nlm4_cancargs.alock.caller_name);
21ab4e
@@ -1603,6 +1616,9 @@ nlm4err:
21ab4e
 
21ab4e
                 nfs3_call_state_wipe (cs);
21ab4e
         }
21ab4e
+
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         /* clean up is taken care of */
21ab4e
         return 0;
21ab4e
 }
21ab4e
@@ -1678,7 +1694,7 @@ nlm4svc_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         nlm4_stats                      stat = nlm4_denied;
21ab4e
         nfs3_call_state_t              *cs = NULL;
21ab4e
 
21ab4e
-        cs = frame->local;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t*) frame->local);
21ab4e
         if (op_ret == -1) {
21ab4e
                 stat = nlm4_errno_to_nlm4stat (op_errno);
21ab4e
                 goto err;
21ab4e
@@ -1691,7 +1707,7 @@ nlm4svc_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
 
21ab4e
 err:
21ab4e
         nlm4_generic_reply (cs->req, cs->args.nlm4_unlockargs.cookie, stat);
21ab4e
-        nfs3_call_state_wipe (cs);
21ab4e
+        GF_REF_PUT (cs);
21ab4e
         return 0;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1705,7 +1721,7 @@ nlm4_unlock_fd_resume (void *carg)
21ab4e
 
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nfs_request_user_init (&nfu, cs->req);
21ab4e
         nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_unlockargs.alock, 0);
21ab4e
         nlm_copy_lkowner (&nfu.lk_owner, &cs->args.nlm4_unlockargs.alock.oh);
21ab4e
@@ -1713,6 +1729,8 @@ nlm4_unlock_fd_resume (void *carg)
21ab4e
         ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLK,
21ab4e
                       &flock, nlm4svc_unlock_cbk, cs);
21ab4e
 
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1728,7 +1746,7 @@ nlm4_unlock_resume (void *carg)
21ab4e
         if (!carg)
21ab4e
                 return ret;
21ab4e
 
21ab4e
-        cs = (nfs3_call_state_t *)carg;
21ab4e
+        cs = GF_REF_GET ((nfs3_call_state_t *)carg);
21ab4e
         nlm4_check_fh_resolve_status (cs, stat, nlm4err);
21ab4e
         caller_name = cs->args.nlm4_unlockargs.alock.caller_name;
21ab4e
 
21ab4e
@@ -1758,6 +1776,9 @@ nlm4err:
21ab4e
 
21ab4e
                 nfs3_call_state_wipe (cs);
21ab4e
         }
21ab4e
+
21ab4e
+        GF_REF_PUT (cs);
21ab4e
+
21ab4e
         /* we have already taken care of cleanup */
21ab4e
         return 0;
21ab4e
 }
21ab4e
@@ -2425,6 +2446,9 @@ nlm_handle_connect (struct rpc_clnt *rpc_clnt, nfs3_call_state_t *cs)
21ab4e
         }
21ab4e
 
21ab4e
 out:
21ab4e
+        if (cs)
21ab4e
+                GF_REF_PUT (cs);
21ab4e
+
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e