Skip to content

Commit 1991ee5

Browse files
committed
Destroy global base allocator in the library destructor
The global base allocator should be destroyed in the library destructor in order to avoid use-after-free. Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 73706ea commit 1991ee5

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

src/base_alloc/base_alloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ typedef struct umf_ba_pool_t umf_ba_pool_t;
2121
umf_ba_pool_t *umf_ba_create(size_t size);
2222
void *umf_ba_alloc(umf_ba_pool_t *pool);
2323
void umf_ba_free(umf_ba_pool_t *pool, void *ptr);
24+
void umf_ba_init(void);
2425
void umf_ba_destroy(umf_ba_pool_t *pool);
26+
void umf_ba_destroy_global(void);
2527

2628
#ifdef __cplusplus
2729
}

src/base_alloc/base_alloc_global.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@
1717
static umf_ba_pool_t *BA_pool = NULL;
1818
static UTIL_ONCE_FLAG ba_is_initialized = UTIL_ONCE_FLAG_INIT;
1919

20-
static void umf_ba_destroy_global(void) {
21-
assert(BA_pool);
22-
umf_ba_destroy(BA_pool);
23-
BA_pool = NULL;
24-
}
25-
2620
static void umf_ba_create_global(void) {
21+
umf_ba_init();
2722
assert(BA_pool == NULL);
2823
BA_pool = umf_ba_create(SIZE_BA_POOL_CHUNK);
24+
assert(BA_pool);
25+
}
26+
27+
void umf_ba_destroy_global(void) {
2928
if (BA_pool) {
30-
atexit(umf_ba_destroy_global);
29+
umf_ba_pool_t *pool = BA_pool;
30+
BA_pool = NULL;
31+
umf_ba_destroy(pool);
3132
}
3233
}
3334

src/base_alloc/base_alloc_linux.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313

1414
#include "base_alloc.h"
1515

16+
// The highest possible priority (101) is used, because the constructor should be called
17+
// as the first one and the destructor as the last one in order to avoid use-after-free.
18+
void __attribute__((constructor(101))) umf_ba_constructor(void) {}
19+
20+
void __attribute__((destructor(101))) umf_ba_destructor(void) {
21+
umf_ba_destroy_global();
22+
}
23+
24+
void umf_ba_init(void) {
25+
// do nothing, additional initialization not needed
26+
}
27+
1628
void *ba_os_alloc(size_t size) {
1729
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
1830
-1, 0);

src/base_alloc/base_alloc_windows.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,38 @@
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
*/
77

8+
#include "base_alloc.h"
89
#include <windows.h>
910

11+
static void umf_ba_constructor(void) {}
12+
13+
static void umf_ba_destructor(void) { umf_ba_destroy_global(); }
14+
15+
#ifdef UMF_SHARED_LIBRARY
16+
17+
// constructor and destructor are handled in libumf_windows.c
18+
19+
void umf_ba_init(void) {
20+
// do nothing, additional initialization not needed
21+
}
22+
23+
#else /* UMF_SHARED_LIBRARY */
24+
25+
INIT_ONCE BA_init_once_flag = INIT_ONCE_STATIC_INIT;
26+
27+
BOOL CALLBACK BAinitOnceCb(PINIT_ONCE InitOnce, PVOID Parameter,
28+
PVOID *lpContext) {
29+
umf_ba_constructor();
30+
atexit(umf_ba_destructor);
31+
return TRUE;
32+
}
33+
34+
void umf_ba_init(void) {
35+
InitOnceExecuteOnce(&BA_init_once_flag, BAinitOnceCb, NULL, NULL);
36+
}
37+
38+
#endif /* UMF_SHARED_LIBRARY */
39+
1040
void *ba_os_alloc(size_t size) {
1141
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
1242
}

src/libumf_windows.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ umf_memory_tracker_handle_t TRACKER = NULL;
1717

1818
static void umfCreate(void) { TRACKER = umfMemoryTrackerCreate(); }
1919

20-
static void umfDestroy(void) { umfMemoryTrackerDestroy(TRACKER); }
20+
static void umfDestroy(void) {
21+
umfMemoryTrackerDestroy(TRACKER);
22+
umf_ba_destroy_global();
23+
}
2124

2225
#if defined(UMF_SHARED_LIBRARY)
2326
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {

0 commit comments

Comments
 (0)