summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2015-07-07 12:40:42 +0530
committerXavier Hernandez <xhernandez@datalab.es>2015-07-21 14:43:10 -0700
commitbdb3591ba86333639c7c604d0f984006e5b8a1de (patch)
treed23c01e6954099b8c64a74034470c50ad15538de
parent1a7d49cfecd75b97641ab9261ee3c930bd51e895 (diff)
cluster/ec: Fix use after free bug
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: 1240284 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> >Reviewed-on: http://review.gluster.org/11558 >Reviewed-by: Xavier Hernandez <xhernandez@datalab.es> >Tested-by: Gluster Build System <jenkins@build.gluster.com> >Tested-by: NetBSD Build System <jenkins@build.gluster.org> BUG: 1243648 Change-Id: I57515d1f478b2a41a20d37368c947049d23778f0 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/11683 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
-rw-r--r--xlators/cluster/ec/src/ec-common.c8
-rw-r--r--xlators/cluster/ec/src/ec-data.c1
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 200aedaa5b1..439773e1ac8 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 2a34f78999c..78c505cc704 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);