Blob Blame History Raw
From 2334f5b162e81d81673b59555baaf0a26189e603 Mon Sep 17 00:00:00 2001
From: Susant Palai <spalai@redhat.com>
Date: Mon, 8 Oct 2018 11:38:09 +0530
Subject: [PATCH 398/399] lock: Do not allow meta-lock count to be more than
 one

In the current scheme of glusterfs where lock migration is
experimental, (ideally) the rebalance process which is migrating
the file should request for a metalock. Hence, the metalock count
should not be more than one for an inode. In future, if there is a
need for meta-lock from other clients, this patch can be reverted.

Since pl_metalk is called as part of setxattr operation, any client
process(non-rebalance) residing outside trusted network can exhaust
memory of the server node by issuing setxattr repetitively on the
metalock key. The current patch makes sure that more than
one metalock cannot be granted on an inode.

Fixes: CVE-2018-14660

Change-Id: I5a1dde0b24b0aedcfb29cc89dffc04ccc5a88bcb
BUG: 1636308
Signed-off-by: Susant Palai <spalai@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/152041
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Tested-by: Amar Tumballi <amarts@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
 xlators/features/locks/src/posix.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index 63f914c..c58e6ba 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -2938,6 +2938,40 @@ pl_metalk (call_frame_t *frame, xlator_t *this, inode_t *inode)
                 goto out;
         }
 
+        /* Non rebalance process trying to do metalock */
+        if (frame->root->pid != GF_CLIENT_PID_DEFRAG) {
+                ret = -1;
+                goto out;
+        }
+
+
+        /* Note: In the current scheme of glusterfs where lock migration is
+         * experimental, (ideally) the rebalance process which is migrating
+         * the file should request for a metalock. Hence, the metalock count
+         * should not be more than one for an inode. In future, if there is a
+         * need for meta-lock from other clients, the following block can be
+         * removed.
+         *
+         * Since pl_metalk is called as part of setxattr operation, any client
+         * process(non-rebalance) residing outside trusted network can exhaust
+         * memory of the server node by issuing setxattr repetitively on the
+         * metalock key. The following code makes sure that more than
+         * one metalock cannot be granted on an inode*/
+        pthread_mutex_lock (&pl_inode->mutex);
+        {
+                if (pl_metalock_is_active(pl_inode)) {
+                        gf_msg (this->name, GF_LOG_WARNING, EINVAL, 0,
+                                "More than one meta-lock can not be granted on"
+                                "the inode");
+                        ret = -1;
+                }
+        }
+        pthread_mutex_lock (&pl_inode->mutex);
+
+        if (ret == -1) {
+                goto out;
+        }
+
         if (frame->root->client) {
                 ctx = pl_ctx_get (frame->root->client, this);
                 if (!ctx) {
@@ -3118,7 +3152,7 @@ pl_setxattr (call_frame_t *frame, xlator_t *this,
              loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
 {
         int             op_ret          = 0;
-        int             op_errno        = 0;
+        int             op_errno        = EINVAL;
         dict_t          *xdata_rsp      = NULL;
 
         PL_LOCAL_GET_REQUESTS (frame, this, xdata, NULL, loc, NULL);
-- 
1.8.3.1