summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
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-07 10:17:11 -0700
commite45f9943e321324988f36eca9dbd4dbd8536b17c (patch)
tree5c8e9d644ba7eeb38a886468be79248ac1767160 /xlators/cluster/ec
parentafa793ff16b349989ca7c958466eae15d2d003f9 (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>
Diffstat (limited to 'xlators/cluster/ec')
-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 8d1196dd0c3..41adbb4c508 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);