summaryrefslogtreecommitdiffstats
path: root/src/quarantine.c
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2013-01-30 23:03:11 (GMT)
committerJason Evans <je@fb.com>2013-01-31 22:23:48 (GMT)
commitbbe29d374d0fa5f4684621f16c099294e56c26ef (patch)
tree4ddaf133e68cb14e25127afb7dfd41a5c8562b34 /src/quarantine.c
parent83789f45307379e096c4e8be81d9e9a51e3f5a4a (diff)
downloadjemalloc-bbe29d374d0fa5f4684621f16c099294e56c26ef.zip
jemalloc-bbe29d374d0fa5f4684621f16c099294e56c26ef.tar.gz
jemalloc-bbe29d374d0fa5f4684621f16c099294e56c26ef.tar.bz2
Fix potential TLS-related memory corruption.
Avoid writing to uninitialized TLS as a side effect of deallocation. Initializing TLS during deallocation is unsafe because it is possible that a thread never did any allocation, and that TLS has already been deallocated by the threads library, resulting in write-after-free corruption. These fixes affect prof_tdata and quarantine; all other uses of TLS are already safe, whether intentionally (as for tcache) or unintentionally (as for arenas).
Diffstat (limited to 'src/quarantine.c')
-rw-r--r--src/quarantine.c55
1 files changed, 13 insertions, 42 deletions
diff --git a/src/quarantine.c b/src/quarantine.c
index 9005ab3..cab7e16 100644
--- a/src/quarantine.c
+++ b/src/quarantine.c
@@ -1,3 +1,4 @@
+#define JEMALLOC_QUARANTINE_C_
#include "jemalloc/internal/jemalloc_internal.h"
/*
@@ -11,39 +12,17 @@
/******************************************************************************/
/* Data. */
-typedef struct quarantine_obj_s quarantine_obj_t;
-typedef struct quarantine_s quarantine_t;
-
-struct quarantine_obj_s {
- void *ptr;
- size_t usize;
-};
-
-struct quarantine_s {
- size_t curbytes;
- size_t curobjs;
- size_t first;
-#define LG_MAXOBJS_INIT 10
- size_t lg_maxobjs;
- quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */
-};
-
-static void quarantine_cleanup(void *arg);
-
-malloc_tsd_data(static, quarantine, quarantine_t *, NULL)
-malloc_tsd_funcs(JEMALLOC_INLINE, quarantine, quarantine_t *, NULL,
- quarantine_cleanup)
+malloc_tsd_data(, quarantine, quarantine_t *, NULL)
/******************************************************************************/
/* Function prototypes for non-inline static functions. */
-static quarantine_t *quarantine_init(size_t lg_maxobjs);
static quarantine_t *quarantine_grow(quarantine_t *quarantine);
static void quarantine_drain(quarantine_t *quarantine, size_t upper_bound);
/******************************************************************************/
-static quarantine_t *
+quarantine_t *
quarantine_init(size_t lg_maxobjs)
{
quarantine_t *quarantine;
@@ -119,24 +98,16 @@ quarantine(void *ptr)
quarantine = *quarantine_tsd_get();
if ((uintptr_t)quarantine <= (uintptr_t)QUARANTINE_STATE_MAX) {
- if (quarantine == NULL) {
- if ((quarantine = quarantine_init(LG_MAXOBJS_INIT)) ==
- NULL) {
- idalloc(ptr);
- return;
- }
- } else {
- if (quarantine == QUARANTINE_STATE_PURGATORY) {
- /*
- * Make a note that quarantine() was called
- * after quarantine_cleanup() was called.
- */
- quarantine = QUARANTINE_STATE_REINCARNATED;
- quarantine_tsd_set(&quarantine);
- }
- idalloc(ptr);
- return;
+ if (quarantine == QUARANTINE_STATE_PURGATORY) {
+ /*
+ * Make a note that quarantine() was called after
+ * quarantine_cleanup() was called.
+ */
+ quarantine = QUARANTINE_STATE_REINCARNATED;
+ quarantine_tsd_set(&quarantine);
}
+ idalloc(ptr);
+ return;
}
/*
* Drain one or more objects if the quarantine size limit would be
@@ -169,7 +140,7 @@ quarantine(void *ptr)
}
}
-static void
+void
quarantine_cleanup(void *arg)
{
quarantine_t *quarantine = *(quarantine_t **)arg;