Blob Blame History Raw
From cd0cfcf3a825c6ea4c943d609fb5a3e391f81b01 Mon Sep 17 00:00:00 2001
From: Pranith Kumar K <pkarampu@redhat.com>
Date: Tue, 7 Jul 2015 12:40:42 +0530
Subject: [PATCH 212/212] cluster/ec: Fix use after free bug

        Backport of http://review.gluster.org/11558

In ec_lock() there is a chance that ec_resume is called on fop even before
ec_sleep.  This can result in refs == 0 for fop leading to use after free in
this function when it calls ec_sleep so do ec_sleep at start and ec_resume at
end of this function.

Change-Id: I879b2667bf71eaa56be1b53b5bdc91b7bb56c650
BUG: 1240245
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/52473
---
 xlators/cluster/ec/src/ec-common.c |    8 ++++++++
 xlators/cluster/ec/src/ec-data.c   |    1 +
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
index 200aeda..439773e 100644
--- a/xlators/cluster/ec/src/ec-common.c
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -244,6 +244,7 @@ void ec_sleep(ec_fop_data_t *fop)
 {
     LOCK(&fop->lock);
 
+    GF_ASSERT (fop->refs > 0);
     fop->refs++;
     fop->jobs++;
 
@@ -1319,6 +1320,12 @@ void ec_lock(ec_fop_data_t *fop)
     ec_lock_link_t *timer_link = NULL;
     ec_lock_t *lock;
 
+    /* There is a chance that ec_resume is called on fop even before ec_sleep.
+     * Which can result in refs == 0 for fop leading to use after free in this
+     * function when it calls ec_sleep so do ec_sleep at start and ec_resume at
+     * the end of this function.*/
+    ec_sleep (fop);
+
     while (fop->locked < fop->lock_count) {
         /* Since there are only up to 2 locks per fop, this xor will change
          * the order of the locks if fop->first_lock is 1. */
@@ -1383,6 +1390,7 @@ void ec_lock(ec_fop_data_t *fop)
             timer_link = NULL;
         }
     }
+    ec_resume (fop, 0);
 
     if (timer_link != NULL) {
         ec_resume(timer_link->fop, 0);
diff --git a/xlators/cluster/ec/src/ec-data.c b/xlators/cluster/ec/src/ec-data.c
index 2a34f78..78c505c 100644
--- a/xlators/cluster/ec/src/ec-data.c
+++ b/xlators/cluster/ec/src/ec-data.c
@@ -258,6 +258,7 @@ void ec_fop_data_release(ec_fop_data_t * fop)
 
     ec_trace("RELEASE", fop, "");
 
+    GF_ASSERT (fop->refs > 0);
     refs = --fop->refs;
 
     UNLOCK(&fop->lock);
-- 
1.7.1