diff options
author | Jason Evans <je@fb.com> | 2013-01-31 22:42:41 (GMT) |
---|---|---|
committer | Jason Evans <je@fb.com> | 2013-01-31 22:43:54 (GMT) |
commit | d0e942e4669b8600b0bd7e5ae132ae26d10a40ed (patch) | |
tree | acdf0a23ff0c7fd4ea8ed43edddc7637d893465e /src/quarantine.c | |
parent | bbe29d374d0fa5f4684621f16c099294e56c26ef (diff) | |
download | jemalloc-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.c | 29 |
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 |