summaryrefslogtreecommitdiffstats
path: root/src/quarantine.c
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2013-01-31 22:42:41 (GMT)
committerJason Evans <je@fb.com>2013-01-31 22:43:54 (GMT)
commitd0e942e4669b8600b0bd7e5ae132ae26d10a40ed (patch)
treeacdf0a23ff0c7fd4ea8ed43edddc7637d893465e /src/quarantine.c
parentbbe29d374d0fa5f4684621f16c099294e56c26ef (diff)
downloadjemalloc-d0e942e4669b8600b0bd7e5ae132ae26d10a40ed.zip
jemalloc-d0e942e4669b8600b0bd7e5ae132ae26d10a40ed.tar.gz
jemalloc-d0e942e4669b8600b0bd7e5ae132ae26d10a40ed.tar.bz2
Fix two quarantine bugs.
Internal reallocation of the quarantined object array leaked the old array. Reallocation failure for internal reallocation of the quarantined object array (very unlikely) resulted in memory corruption.
Diffstat (limited to 'src/quarantine.c')
-rw-r--r--src/quarantine.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/quarantine.c b/src/quarantine.c
index cab7e16..f96a948 100644
--- a/src/quarantine.c
+++ b/src/quarantine.c
@@ -18,6 +18,7 @@ malloc_tsd_data(, quarantine, quarantine_t *, NULL)
/* Function prototypes for non-inline static functions. */
static quarantine_t *quarantine_grow(quarantine_t *quarantine);
+static void quarantine_drain_one(quarantine_t *quarantine);
static void quarantine_drain(quarantine_t *quarantine, size_t upper_bound);
/******************************************************************************/
@@ -47,8 +48,10 @@ quarantine_grow(quarantine_t *quarantine)
quarantine_t *ret;
ret = quarantine_init(quarantine->lg_maxobjs + 1);
- if (ret == NULL)
+ if (ret == NULL) {
+ quarantine_drain_one(quarantine);
return (quarantine);
+ }
ret->curbytes = quarantine->curbytes;
ret->curobjs = quarantine->curobjs;
@@ -68,23 +71,29 @@ quarantine_grow(quarantine_t *quarantine)
memcpy(&ret->objs[ncopy_a], quarantine->objs, ncopy_b *
sizeof(quarantine_obj_t));
}
+ idalloc(quarantine);
return (ret);
}
static void
+quarantine_drain_one(quarantine_t *quarantine)
+{
+ quarantine_obj_t *obj = &quarantine->objs[quarantine->first];
+ assert(obj->usize == isalloc(obj->ptr, config_prof));
+ idalloc(obj->ptr);
+ quarantine->curbytes -= obj->usize;
+ quarantine->curobjs--;
+ quarantine->first = (quarantine->first + 1) & ((ZU(1) <<
+ quarantine->lg_maxobjs) - 1);
+}
+
+static void
quarantine_drain(quarantine_t *quarantine, size_t upper_bound)
{
- while (quarantine->curbytes > upper_bound && quarantine->curobjs > 0) {
- quarantine_obj_t *obj = &quarantine->objs[quarantine->first];
- assert(obj->usize == isalloc(obj->ptr, config_prof));
- idalloc(obj->ptr);
- quarantine->curbytes -= obj->usize;
- quarantine->curobjs--;
- quarantine->first = (quarantine->first + 1) & ((ZU(1) <<
- quarantine->lg_maxobjs) - 1);
- }
+ while (quarantine->curbytes > upper_bound && quarantine->curobjs > 0)
+ quarantine_drain_one(quarantine);
}
void