887953
From 2334f5b162e81d81673b59555baaf0a26189e603 Mon Sep 17 00:00:00 2001
887953
From: Susant Palai <spalai@redhat.com>
887953
Date: Mon, 8 Oct 2018 11:38:09 +0530
887953
Subject: [PATCH 398/399] lock: Do not allow meta-lock count to be more than
887953
 one
887953
887953
In the current scheme of glusterfs where lock migration is
887953
experimental, (ideally) the rebalance process which is migrating
887953
the file should request for a metalock. Hence, the metalock count
887953
should not be more than one for an inode. In future, if there is a
887953
need for meta-lock from other clients, this patch can be reverted.
887953
887953
Since pl_metalk is called as part of setxattr operation, any client
887953
process(non-rebalance) residing outside trusted network can exhaust
887953
memory of the server node by issuing setxattr repetitively on the
887953
metalock key. The current patch makes sure that more than
887953
one metalock cannot be granted on an inode.
887953
887953
Fixes: CVE-2018-14660
887953
887953
Change-Id: I5a1dde0b24b0aedcfb29cc89dffc04ccc5a88bcb
887953
BUG: 1636308
887953
Signed-off-by: Susant Palai <spalai@redhat.com>
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/152041
887953
Reviewed-by: Amar Tumballi <amarts@redhat.com>
887953
Tested-by: Amar Tumballi <amarts@redhat.com>
887953
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
887953
---
887953
 xlators/features/locks/src/posix.c | 36 +++++++++++++++++++++++++++++++++++-
887953
 1 file changed, 35 insertions(+), 1 deletion(-)
887953
887953
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
887953
index 63f914c..c58e6ba 100644
887953
--- a/xlators/features/locks/src/posix.c
887953
+++ b/xlators/features/locks/src/posix.c
887953
@@ -2938,6 +2938,40 @@ pl_metalk (call_frame_t *frame, xlator_t *this, inode_t *inode)
887953
                 goto out;
887953
         }
887953
 
887953
+        /* Non rebalance process trying to do metalock */
887953
+        if (frame->root->pid != GF_CLIENT_PID_DEFRAG) {
887953
+                ret = -1;
887953
+                goto out;
887953
+        }
887953
+
887953
+
887953
+        /* Note: In the current scheme of glusterfs where lock migration is
887953
+         * experimental, (ideally) the rebalance process which is migrating
887953
+         * the file should request for a metalock. Hence, the metalock count
887953
+         * should not be more than one for an inode. In future, if there is a
887953
+         * need for meta-lock from other clients, the following block can be
887953
+         * removed.
887953
+         *
887953
+         * Since pl_metalk is called as part of setxattr operation, any client
887953
+         * process(non-rebalance) residing outside trusted network can exhaust
887953
+         * memory of the server node by issuing setxattr repetitively on the
887953
+         * metalock key. The following code makes sure that more than
887953
+         * one metalock cannot be granted on an inode*/
887953
+        pthread_mutex_lock (&pl_inode->mutex);
887953
+        {
887953
+                if (pl_metalock_is_active(pl_inode)) {
887953
+                        gf_msg (this->name, GF_LOG_WARNING, EINVAL, 0,
887953
+                                "More than one meta-lock can not be granted on"
887953
+                                "the inode");
887953
+                        ret = -1;
887953
+                }
887953
+        }
887953
+        pthread_mutex_lock (&pl_inode->mutex);
887953
+
887953
+        if (ret == -1) {
887953
+                goto out;
887953
+        }
887953
+
887953
         if (frame->root->client) {
887953
                 ctx = pl_ctx_get (frame->root->client, this);
887953
                 if (!ctx) {
887953
@@ -3118,7 +3152,7 @@ pl_setxattr (call_frame_t *frame, xlator_t *this,
887953
              loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
887953
 {
887953
         int             op_ret          = 0;
887953
-        int             op_errno        = 0;
887953
+        int             op_errno        = EINVAL;
887953
         dict_t          *xdata_rsp      = NULL;
887953
 
887953
         PL_LOCAL_GET_REQUESTS (frame, this, xdata, NULL, loc, NULL);
887953
-- 
887953
1.8.3.1
887953