From b33bb0943ac4957eaf7b16ef694a4e4b4a538212 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 31 Oct 2019 15:50:58 +0000 Subject: libtokencap/libdislocator README rename proposals and fixing the install tasks in the process. --- libdislocator/README.dislocator.md | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 libdislocator/README.dislocator.md (limited to 'libdislocator/README.dislocator.md') diff --git a/libdislocator/README.dislocator.md b/libdislocator/README.dislocator.md new file mode 100644 index 00000000..5d5a1464 --- /dev/null +++ b/libdislocator/README.dislocator.md @@ -0,0 +1,60 @@ +# libdislocator, an abusive allocator + + (See ../docs/README for the general instruction manual.) + +This is a companion library that can be used as a drop-in replacement for the +libc allocator in the fuzzed binaries. It improves the odds of bumping into +heap-related security bugs in several ways: + + - It allocates all buffers so that they are immediately adjacent to a + subsequent PROT_NONE page, causing most off-by-one reads and writes to + immediately segfault, + + - It adds a canary immediately below the allocated buffer, to catch writes + to negative offsets (won't catch reads, though), + + - It sets the memory returned by malloc() to garbage values, improving the + odds of crashing when the target accesses uninitialized data, + + - It sets freed memory to PROT_NONE and does not actually reuse it, causing + most use-after-free bugs to segfault right away, + + - It forces all realloc() calls to return a new address - and sets + PROT_NONE on the original block. This catches use-after-realloc bugs, + + - It checks for calloc() overflows and can cause soft or hard failures + of alloc requests past a configurable memory limit (AFL_LD_LIMIT_MB, + AFL_LD_HARD_FAIL). + +Basically, it is inspired by some of the non-default options available for the +OpenBSD allocator - see malloc.conf(5) on that platform for reference. It is +also somewhat similar to several other debugging libraries, such as gmalloc +and DUMA - but is simple, plug-and-play, and designed specifically for fuzzing +jobs. + +Note that it does nothing for stack-based memory handling errors. The +-fstack-protector-all setting for GCC / clang, enabled when using AFL_HARDEN, +can catch some subset of that. + +The allocator is slow and memory-intensive (even the tiniest allocation uses up +4 kB of physical memory and 8 kB of virtual mem), making it completely unsuitable +for "production" uses; but it can be faster and more hassle-free than ASAN / MSAN +when fuzzing small, self-contained binaries. + +To use this library, run AFL like so: + +``` +AFL_PRELOAD=/path/to/libdislocator.so ./afl-fuzz [...other params...] +``` + +You *have* to specify path, even if it's just ./libdislocator.so or +$PWD/libdislocator.so. + +Similarly to afl-tmin, the library is not "proprietary" and can be used with +other fuzzers or testing tools without the need for any code tweaks. It does not +require AFL-instrumented binaries to work. + +Note that the AFL_PRELOAD approach (which AFL internally maps to LD_PRELOAD or +DYLD_INSERT_LIBRARIES, depending on the OS) works only if the target binary is +dynamically linked. Otherwise, attempting to use the library will have no +effect. -- cgit 1.4.1 From 3ce808688f793a72bcd28b31d0766fc90304c622 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 7 Nov 2019 04:56:57 +0000 Subject: Little additions from feedback --- libdislocator/Makefile | 4 ++++ libdislocator/README.dislocator.md | 2 ++ libdislocator/libdislocator.so.c | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'libdislocator/README.dislocator.md') diff --git a/libdislocator/Makefile b/libdislocator/Makefile index 05ba26b3..216d2862 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -21,6 +21,10 @@ VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) CFLAGS ?= -O3 -funroll-loops -I ../include/ CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +ifdef USEHUGEPAGE + CFLAGS += -DUSEHUGEPAGE +endif + all: libdislocator.so libdislocator.so: libdislocator.so.c ../config.h diff --git a/libdislocator/README.dislocator.md b/libdislocator/README.dislocator.md index 5d5a1464..77626901 100644 --- a/libdislocator/README.dislocator.md +++ b/libdislocator/README.dislocator.md @@ -25,6 +25,8 @@ heap-related security bugs in several ways: - It checks for calloc() overflows and can cause soft or hard failures of alloc requests past a configurable memory limit (AFL_LD_LIMIT_MB, AFL_LD_HARD_FAIL). + - Optionally, in platforms supporting it, huge pages can be used by passing + USEHUGEPAGE=1 to make. Basically, it is inspired by some of the non-default options available for the OpenBSD allocator - see malloc.conf(5) on that platform for reference. It is diff --git a/libdislocator/libdislocator.so.c b/libdislocator/libdislocator.so.c index eb8e9de3..0268cc52 100644 --- a/libdislocator/libdislocator.so.c +++ b/libdislocator/libdislocator.so.c @@ -111,6 +111,7 @@ static __thread u32 call_depth; /* To avoid recursion via fprintf() */ static void* __dislocator_alloc(size_t len) { void* ret; + size_t tlen; int flags, fd, sp; if (total_mem + len > max_mem || total_mem + len < total_mem) { @@ -123,6 +124,7 @@ static void* __dislocator_alloc(size_t len) { } + tlen = (1 + PG_COUNT(len + 8)) * PAGE_SIZE; flags = MAP_PRIVATE | MAP_ANONYMOUS; fd = -1; #if defined(USEHUGEPAGE) @@ -142,8 +144,22 @@ static void* __dislocator_alloc(size_t len) { /* We will also store buffer length and a canary below the actual buffer, so let's add 8 bytes for that. */ - ret = mmap(NULL, (1 + PG_COUNT(len + 8)) * PAGE_SIZE, PROT_READ | PROT_WRITE, + ret = mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0); +#if defined(USEHUGEPAGE) + /* We try one more time with regular call */ + if (ret == MAP_FAILED) { +#if defined(__APPLE__) + fd = -1; +#elif defined(__linux__) + flags &= -MAP_HUGETLB; +#elif defined(__FreeBSD__) + flags &= -MAP_ALIGNED_SUPER; +#endif + ret = mmap(NULL, tlen, PROT_READ | PROT_WRITE, + flags, fd, 0); + } +#endif if (ret == MAP_FAILED) { -- cgit 1.4.1