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