Skip to content

Commit c79cdc8

Browse files
cube0x8rmalmain
andauthored
add mmap hooks to libqasan (#2122)
* add mmap hooks to libqasan --------- Co-authored-by: Romain Malmain <[email protected]>
1 parent 935100e commit c79cdc8

File tree

4 files changed

+142
-1
lines changed

4 files changed

+142
-1
lines changed

libafl_qemu/libqasan/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ OUT_DIR ?= .
1818
override CFLAGS += -Wno-int-to-void-pointer-cast -ggdb -O1 -fno-builtin -Wno-unused-result
1919
override LDFLAGS += -ldl -pthread
2020

21-
SRC := libqasan.c hooks.c malloc.c string.c uninstrument.c patch.c dlmalloc.c printf/printf.c
21+
SRC := libqasan.c hooks.c malloc.c mmap.c string.c uninstrument.c patch.c dlmalloc.c printf/printf.c
2222
HDR := libqasan.h qasan.h map_macro.h printf/printf.h
2323

2424
all: $(OUT_DIR)/libgasan.so $(OUT_DIR)/libqasan.so

libafl_qemu/libqasan/hooks.c

+20
Original file line numberDiff line numberDiff line change
@@ -632,3 +632,23 @@ int vasprintf(char **restrict strp, const char *restrict fmt, va_list ap) {
632632

633633
return len;
634634
}
635+
636+
void *mmap(void *addr, size_t length, int prot, int flags, int fd,
637+
off_t offset) {
638+
void *rtv = __builtin_return_address(0);
639+
QASAN_DEBUG("%14p: mmap(%p, %zu, %d, %d, %d, %ld)\n", rtv, addr, length, prot,
640+
flags, fd, offset);
641+
void *r = __libqasan_mmap(addr, length, prot, flags, fd, offset);
642+
QASAN_DEBUG("\t\t = %p\n", r);
643+
644+
return r;
645+
}
646+
647+
int munmap(void *addr, size_t length) {
648+
void *rtv = __builtin_return_address(0);
649+
QASAN_DEBUG("%14p: munmap(%p, %zu)\n", rtv, addr, length);
650+
int r = __libqasan_munmap(addr, length);
651+
QASAN_DEBUG("\t\t = %d\n", r);
652+
653+
return r;
654+
}

libafl_qemu/libqasan/libqasan.h

+3
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,8 @@ char *__libqasan_strrchr(const char *s, int c);
125125
size_t __libqasan_wcslen(const wchar_t *s);
126126
wchar_t *__libqasan_wcscpy(wchar_t *d, const wchar_t *s);
127127
int __libqasan_wcscmp(const wchar_t *s1, const wchar_t *s2);
128+
void *__libqasan_mmap(void *addr, size_t length, int prot, int flags, int fd,
129+
off_t offset);
130+
int __libqasan_munmap(void *addr, size_t length);
128131

129132
#endif

libafl_qemu/libqasan/mmap.c

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*******************************************************************************
2+
Copyright (c) 2019-2024, Andrea Fioraldi
3+
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
*******************************************************************************/
26+
27+
/*
28+
Mmap hooks for libqasan by Alessandro "cube" De Vito
29+
30+
31+
*/
32+
33+
#include "libqasan.h"
34+
#include <features.h>
35+
#include <errno.h>
36+
#include <stddef.h>
37+
#include <assert.h>
38+
#include <pthread.h>
39+
#include <sys/mman.h>
40+
41+
#ifdef __GLIBC__
42+
#define USE_LIBC_ALLOC
43+
#endif
44+
45+
#if __STDC_VERSION__ < 201112L || \
46+
(defined(__FreeBSD__) && __FreeBSD_version < 1200000)
47+
// use this hack if not C11
48+
typedef struct {
49+
long long __ll;
50+
long double __ld;
51+
52+
} max_align_t;
53+
54+
#endif
55+
56+
#ifdef USE_LIBC_ALLOC
57+
58+
void *(*__lq_libc_mmap)(void *, size_t, int, int, int, off_t);
59+
int (*__lq_libc_munmap)(void *, size_t);
60+
61+
#else
62+
63+
// TODO: include from mmap.c
64+
65+
#endif
66+
67+
int __libqasan_mmap_initialized;
68+
69+
void __libqasan_init_mmap(void) {
70+
if (__libqasan_mmap_initialized) return;
71+
72+
#ifdef USE_LIBC_ALLOC
73+
__lq_libc_mmap = dlsym(RTLD_NEXT, "mmap");
74+
__lq_libc_munmap = dlsym(RTLD_NEXT, "munmap");
75+
#endif
76+
77+
__libqasan_mmap_initialized = 1;
78+
QASAN_LOG("\n");
79+
QASAN_LOG("mmap initialization done.\n");
80+
QASAN_LOG("\n");
81+
}
82+
83+
void *__libqasan_mmap(void *addr, size_t length, int prot, int flags, int fd,
84+
off_t offset) {
85+
__libqasan_init_mmap();
86+
87+
int state = QASAN_SWAP(QASAN_DISABLED); // disable qasan for this thread
88+
void *p = __lq_libc_mmap(addr, length, prot, flags, fd, offset);
89+
QASAN_SWAP(state);
90+
91+
if (!p) return NULL;
92+
93+
QASAN_UNPOISON(p, length);
94+
95+
QASAN_ALLOC(p, (uintptr_t)p + length);
96+
97+
// We don't memset the memory, as it's not guaranteed to be writable.
98+
99+
return p;
100+
}
101+
102+
int __libqasan_munmap(void *addr, size_t length) {
103+
__libqasan_init_mmap();
104+
105+
int state = QASAN_SWAP(QASAN_DISABLED); // disable qasan for this thread
106+
int ret = __lq_libc_munmap(addr, length);
107+
QASAN_SWAP(state);
108+
109+
if (ret == -1) return -1;
110+
111+
// Omitting memory poisoning for unmapped regions as accessing them would
112+
// result in an error anyway.
113+
114+
// TODO: add a syscall to deallocate addr->addr + length
115+
QASAN_DEALLOC(addr);
116+
117+
return ret;
118+
}

0 commit comments

Comments
 (0)