diff options
author | van Hauser <vh@thc.org> | 2024-04-17 12:55:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-17 12:55:34 +0200 |
commit | f138ab8ac682caa3ecec1773ee4e7fd0aac12f79 (patch) | |
tree | 7331d05dfb93572050dbe0ce1d7a175c35074ec9 | |
parent | 6b049536f1614892df99f7c1ebd7710192b607a8 (diff) | |
parent | 50839cf6e92c5f518ee2045452e7ff7a522c4d6f (diff) | |
download | afl++-f138ab8ac682caa3ecec1773ee4e7fd0aac12f79.tar.gz |
Merge pull request #2059 from elboulangero/afl-gcc
Fix afl-gcc
-rw-r--r-- | src/afl-cc.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c index 45fd398b..dd4fb4ea 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -17,6 +17,10 @@ #define AFL_MAIN +#ifndef _GNU_SOURCE + #define _GNU_SOURCE 1 +#endif + #include "common.h" #include "config.h" #include "types.h" @@ -32,7 +36,9 @@ #include <limits.h> #include <assert.h> #include <ctype.h> +#include <fcntl.h> #include <sys/stat.h> +#include <sys/mman.h> #if (LLVM_MAJOR - 0 == 0) #undef LLVM_MAJOR @@ -464,6 +470,8 @@ u8 *find_object(aflcc_state_t *aflcc, u8 *obj) { *slash = 0; tmp = alloc_printf("%s/%s", exepath, obj); + if (aflcc->debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { return tmp; } ck_free(tmp); @@ -518,7 +526,7 @@ void find_built_deps(aflcc_state_t *aflcc) { char *ptr = NULL; #if defined(__x86_64__) - if ((ptr = find_object(aflcc, "as")) != NULL) { + if ((ptr = find_object(aflcc, "afl-as")) != NULL) { #ifndef __APPLE__ // on OSX clang masquerades as GCC @@ -2473,13 +2481,60 @@ void add_runtime(aflcc_state_t *aflcc) { */ void add_assembler(aflcc_state_t *aflcc) { - u8 *afl_as = find_object(aflcc, "as"); + u8 *afl_as = find_object(aflcc, "afl-as"); - if (!afl_as) FATAL("Cannot find 'as' (symlink to 'afl-as')."); + if (!afl_as) FATAL("Cannot find 'afl-as'."); u8 *slash = strrchr(afl_as, '/'); if (slash) *slash = 0; + // Search for 'as' may be unreliable in some cases (see #2058) + // so use 'afl-as' instead, because 'as' is usually a symbolic link, + // or can be a renamed copy of 'afl-as' created in the same dir. + // Now we should verify if the compiler can find the 'as' we need. + +#define AFL_AS_ERR "(should be a symlink or copy of 'afl-as')" + + u8 *afl_as_dup = alloc_printf("%s/as", afl_as); + + int fd = open(afl_as_dup, O_RDONLY); + if (fd < 0) { PFATAL("Unable to open '%s' " AFL_AS_ERR, afl_as_dup); } + + struct stat st; + if (fstat(fd, &st) < 0) { + + PFATAL("Unable to fstat '%s' " AFL_AS_ERR, afl_as_dup); + + } + + u32 f_len = st.st_size; + + u8 *f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0); + if (f_data == MAP_FAILED) { + + PFATAL("Unable to mmap file '%s' " AFL_AS_ERR, afl_as_dup); + + } + + close(fd); + + // "AFL_AS" is a const str passed to getenv in afl-as.c + if (!memmem(f_data, f_len, "AFL_AS", strlen("AFL_AS") + 1)) { + + FATAL( + "Looks like '%s' is not a valid symlink or copy of '%s/afl-as'. " + "It is a prerequisite to override system-wide 'as' for " + "instrumentation.", + afl_as_dup, afl_as); + + } + + if (munmap(f_data, f_len)) { PFATAL("unmap() failed"); } + + ck_free(afl_as_dup); + +#undef AFL_AS_ERR + insert_param(aflcc, "-B"); insert_param(aflcc, afl_as); |