Skip to content

Commit 0fb212d

Browse files
Merge pull request #17 from realmadsci/qemu-consistent-preload
Make afl-qemu-trace handle AFL_PRELOAD and AFL_USE_QASAN itself
2 parents d1ca56b + 7f133ec commit 0fb212d

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

linux-user/main.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,73 @@ CPUArchState *cpu_copy(CPUArchState *env)
224224
return new_env;
225225
}
226226

227+
/* A shorthand way to suppress the warnings that you are ignoring the return value of asprintf() */
228+
static inline void ignore_result(long long int unused_result)
229+
{
230+
(void) unused_result;
231+
}
232+
233+
/* Get libqasan path. */
234+
#ifndef AFL_PATH
235+
#define AFL_PATH "/usr/local/lib/afl/"
236+
#endif
237+
static char *get_libqasan_path(char *own_loc)
238+
{
239+
if (!unlikely(own_loc)) {
240+
fprintf(stderr, "BUG: param own_loc is NULL\n");
241+
exit(EXIT_FAILURE);
242+
}
243+
244+
char *tmp, *cp = NULL, *rsl, *own_copy;
245+
246+
tmp = getenv("AFL_PATH");
247+
if (tmp) {
248+
ignore_result(asprintf(&cp, "%s/libqasan.so", tmp));
249+
if (access(cp, X_OK)) {
250+
fprintf(stderr, "Unable to find '%s'\n", tmp);
251+
exit(EXIT_FAILURE);
252+
}
253+
254+
return cp;
255+
}
256+
257+
own_copy = strdup(own_loc);
258+
rsl = strrchr(own_copy, '/');
259+
if (rsl) {
260+
*rsl = 0;
261+
262+
ignore_result(asprintf(&cp, "%s/libqasan.so", own_copy));
263+
free(own_copy);
264+
265+
if (!access(cp, X_OK)) { return cp; }
266+
267+
} else {
268+
free(own_copy);
269+
}
270+
271+
if (!access(AFL_PATH "/libqasan.so", X_OK)) {
272+
if (cp) { free(cp); }
273+
274+
return strdup(AFL_PATH "/libqasan.so");
275+
}
276+
277+
/* This is an AFL error message, but since it is in QEMU it can't
278+
have all the pretty formatting of AFL without importing
279+
a bunch of AFL pieces. */
280+
fprintf(stderr, "\n" "" "[-] " ""
281+
"Oops, unable to find the 'libqasan.so' binary. The binary must be "
282+
"built\n"
283+
" separately by following the instructions in "
284+
"qemu_mode/libqasan/README.md. "
285+
"If you\n"
286+
" already have the binary installed, you may need to specify "
287+
"AFL_PATH in the\n"
288+
" environment.\n");
289+
290+
fprintf(stderr, "Failed to locate 'libqasan.so'.\n");
291+
exit(EXIT_FAILURE);
292+
}
293+
227294
static void handle_arg_help(const char *arg)
228295
{
229296
usage(EXIT_SUCCESS);
@@ -658,6 +725,45 @@ int main(int argc, char **argv, char **envp)
658725
(void) envlist_setenv(envlist, *wrk);
659726
}
660727

728+
/* Add AFL_PRELOAD for qasan if it is enabled */
729+
if(use_qasan) {
730+
char *preload = getenv("AFL_PRELOAD");
731+
char *libqasan = get_libqasan_path(argv[0]);
732+
733+
if (!preload) {
734+
setenv("AFL_PRELOAD", libqasan, 0);
735+
} else {
736+
/* NOTE: If there is more than one in the list, LD_PRELOAD allows spaces or colons
737+
as separators (but no escaping provided), but DYLD_INSERT_LIBRARIES allows only colons.
738+
Prefer colons for maximum compatibility, but use space if the string already has any. */
739+
char * afl_preload;
740+
if (strchr(preload, ' ')) {
741+
ignore_result(asprintf(&afl_preload, "%s %s", libqasan, preload));
742+
} else {
743+
ignore_result(asprintf(&afl_preload, "%s:%s", libqasan, preload));
744+
}
745+
746+
setenv("AFL_PRELOAD", afl_preload, 1);
747+
free(afl_preload);
748+
}
749+
free(libqasan);
750+
}
751+
752+
/* Expand AFL_PRELOAD to append preload libraries */
753+
char *afl_preload = getenv("AFL_PRELOAD");
754+
if (afl_preload) {
755+
/* NOTE: If there is more than one in the list, LD_PRELOAD allows spaces or colons
756+
as separators, but DYLD_INSERT_LIBRARIES allows only colons.
757+
Maybe we should attempt to normalize the list here before we assign it? */
758+
char * ld_preload;
759+
ignore_result(asprintf(&ld_preload, "LD_PRELOAD=%s", afl_preload));
760+
envlist_setenv(envlist, ld_preload);
761+
762+
char * dyld_insert;
763+
ignore_result(asprintf(&dyld_insert, "DYLD_INSERT_LIBRARIES=%s", afl_preload));
764+
envlist_setenv(envlist, dyld_insert);
765+
}
766+
661767
/* Read the stack limit from the kernel. If it's "unlimited",
662768
then we can do little else besides use the default. */
663769
{

0 commit comments

Comments
 (0)