support replacing C++ new/delete implementation

This adds support for sanity checks based on sized deallocation and will
reduce the overhead of calls through the C++ allocator.
This commit is contained in:
Daniel Micay 2018-09-19 13:57:35 -04:00
parent 3dc49f8f73
commit e6e9ac1fc9
3 changed files with 101 additions and 0 deletions

View File

@ -1,14 +1,23 @@
CONFIG_CXX_ALLOCATOR := true
CPPFLAGS := -D_GNU_SOURCE CPPFLAGS := -D_GNU_SOURCE
CFLAGS := -std=c11 -Wall -Wextra -Wmissing-prototypes -O2 -flto -fPIC -fvisibility=hidden -fno-plt -pipe CFLAGS := -std=c11 -Wall -Wextra -Wmissing-prototypes -O2 -flto -fPIC -fvisibility=hidden -fno-plt -pipe
CXXFLAGS := -std=c++14 -Wall -Wextra -O2 -flto -fPIC -fvisibility=hidden -fno-plt -pipe
LDFLAGS := -Wl,-z,defs,-z,relro,-z,now,-z,nodlopen,-z,text LDFLAGS := -Wl,-z,defs,-z,relro,-z,now,-z,nodlopen,-z,text
OBJECTS := chacha.o malloc.o memory.o pages.o random.o util.o OBJECTS := chacha.o malloc.o memory.o pages.o random.o util.o
ifeq ($(CONFIG_CXX_ALLOCATOR),true)
LDLIBS += -lstdc++
OBJECTS += new.o
endif
hardened_malloc.so: $(OBJECTS) hardened_malloc.so: $(OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@ $(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@
chacha.o: chacha.c chacha.h chacha.o: chacha.c chacha.h
malloc.o: malloc.c malloc.h mutex.h config.h memory.h pages.h random.h util.h malloc.o: malloc.c malloc.h mutex.h config.h memory.h pages.h random.h util.h
memory.o: memory.c memory.h util.h memory.o: memory.c memory.h util.h
new.o: new.cc
pages.o: pages.c pages.h memory.h util.h pages.o: pages.c pages.h memory.h util.h
random.o: random.c random.h chacha.h util.h random.o: random.c random.h chacha.h util.h
util.o: util.c util.h util.o: util.c util.h

View File

@ -53,6 +53,16 @@ libraries.
# Configuration # Configuration
You can set some configuration options at compile-time via arguments to the
make command as follows:
make CONFIG_EXAMPLE=false
The available configuration options are the following:
* `CONFIG_CXX_ALLOCATOR`: `true` (default) or `false` to control whether the
C++ allocator is replaced
Compile-time configuration is available in the `config.h` file for controlling Compile-time configuration is available in the `config.h` file for controlling
the balance between security and performance / memory usage. By default, all the balance between security and performance / memory usage. By default, all
the optional security features are enabled. Options are only provided for the the optional security features are enabled. Options are only provided for the

82
new.cc Normal file
View File

@ -0,0 +1,82 @@
#include <stdlib.h>
#include <new>
#include <bits/functexcept.h>
#define noreturn
extern "C" {
#include "malloc.h"
#include "util.h"
}
COLD static void *handle_out_of_memory(size_t size, bool nothrow) {
void *ptr;
do {
std::new_handler handler = std::get_new_handler();
if (handler == nullptr) {
break;
}
try {
handler();
} catch (const std::bad_alloc &) {
break;
}
ptr = h_malloc(size);
} while (ptr == nullptr);
if (ptr == nullptr && !nothrow) {
std::__throw_bad_alloc();
}
return ptr;
}
static inline void *new_impl(size_t size, bool nothrow) {
void *ptr = h_malloc(size);
if (likely(ptr != nullptr)) {
return ptr;
}
return handle_out_of_memory(size, nothrow);
}
void *operator new(size_t size) {
return new_impl(size, false);
}
void *operator new[](size_t size) {
return new_impl(size, false);
}
void *operator new(size_t size, const std::nothrow_t &) noexcept {
return new_impl(size, true);
}
void *operator new[](size_t size, const std::nothrow_t &) noexcept {
return new_impl(size, true);
}
void operator delete(void *ptr) noexcept {
h_free(ptr);
}
void operator delete[](void *ptr) noexcept {
h_free(ptr);
}
void operator delete(void *ptr, const std::nothrow_t &) noexcept {
h_free(ptr);
}
void operator delete[](void *ptr, const std::nothrow_t &) noexcept {
h_free(ptr);
}
void operator delete(void *ptr, size_t size) noexcept {
h_free_sized(ptr, size);
}
void operator delete[](void *ptr, size_t size) noexcept {
h_free_sized(ptr, size);
}