diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2015-07-07 12:40:42 +0530 |
---|---|---|
committer | Xavier Hernandez <xhernandez@datalab.es> | 2015-07-21 14:43:10 -0700 |
commit | bdb3591ba86333639c7c604d0f984006e5b8a1de (patch) | |
tree | d23c01e6954099b8c64a74034470c50ad15538de | |
parent | 1a7d49cfecd75b97641ab9261ee3c930bd51e895 (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.c | 8 | ||||
-rw-r--r-- | 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 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); |