mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-08 16:21:32 +00:00
fixed map location support for LTO
This commit is contained in:
parent
3502db1ac5
commit
cce8c4dbae
@ -466,8 +466,10 @@ void *reallocarray(void *ptr, size_t elem_len, size_t elem_cnt) {
|
|||||||
|
|
||||||
#if !defined(__ANDROID__)
|
#if !defined(__ANDROID__)
|
||||||
size_t malloc_usable_size(void *ptr) {
|
size_t malloc_usable_size(void *ptr) {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
size_t malloc_usable_size(const void *ptr) {
|
size_t malloc_usable_size(const void *ptr) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ptr ? PTR_L(ptr) : 0;
|
return ptr ? PTR_L(ptr) : 0;
|
||||||
@ -498,3 +500,4 @@ __attribute__((constructor)) void __dislocator_init(void) {
|
|||||||
align_allocations = !!getenv("AFL_ALIGNED_ALLOC");
|
align_allocations = !!getenv("AFL_ALIGNED_ALLOC");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -154,6 +155,7 @@ class AFLLTOPass : public ModulePass {
|
|||||||
protected:
|
protected:
|
||||||
int afl_global_id = 1, debug = 0, autodictionary = 0;
|
int afl_global_id = 1, debug = 0, autodictionary = 0;
|
||||||
uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0;
|
uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0;
|
||||||
|
uint64_t map_addr = 0x10000;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,9 +167,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
std::vector<std::string> dictionary;
|
std::vector<std::string> dictionary;
|
||||||
std::vector<CallInst *> calls;
|
std::vector<CallInst *> calls;
|
||||||
DenseMap<Value *, std::string *> valueMap;
|
DenseMap<Value *, std::string *> valueMap;
|
||||||
|
char * ptr;
|
||||||
|
|
||||||
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
||||||
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
||||||
|
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
|
||||||
|
|
||||||
if (getenv("AFL_DEBUG")) debug = 1;
|
if (getenv("AFL_DEBUG")) debug = 1;
|
||||||
|
|
||||||
@ -186,13 +190,64 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
|
getenv("AFL_LLVM_LTO_AUTODICTIONARY"))
|
||||||
autodictionary = 1;
|
autodictionary = 1;
|
||||||
|
|
||||||
|
if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
|
||||||
|
|
||||||
|
if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
|
||||||
|
|
||||||
|
uint64_t val;
|
||||||
|
if (!*ptr || !strcmp(ptr, "0") || !strcmp(ptr, "0x0")) {
|
||||||
|
|
||||||
|
map_addr = 0;
|
||||||
|
|
||||||
|
} else if (map_addr == 0) {
|
||||||
|
|
||||||
|
FATAL(
|
||||||
|
"AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together");
|
||||||
|
|
||||||
|
} else if (strncmp(ptr, "0x", 2) != 0) {
|
||||||
|
|
||||||
|
map_addr = 0x10000; // the default
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
val = strtoull(ptr, NULL, 16);
|
||||||
|
if (val < 0x100 || val > 0xffffffff00000000) {
|
||||||
|
|
||||||
|
FATAL(
|
||||||
|
"AFL_LLVM_MAP_ADDR must be a value between 0x100 and "
|
||||||
|
"0xffffffff00000000");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
map_addr = val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); }
|
||||||
|
|
||||||
/* Get globals for the SHM region and the previous location. Note that
|
/* Get globals for the SHM region and the previous location. Note that
|
||||||
__afl_prev_loc is thread-local. */
|
__afl_prev_loc is thread-local. */
|
||||||
|
|
||||||
GlobalVariable *AFLMapPtr =
|
GlobalVariable *AFLMapPtr = NULL;
|
||||||
|
;
|
||||||
|
Value *MapPtrFixed = NULL;
|
||||||
|
|
||||||
|
if (!map_addr) {
|
||||||
|
|
||||||
|
AFLMapPtr =
|
||||||
new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
|
new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
|
||||||
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
|
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
|
||||||
|
MapPtrFixed =
|
||||||
|
ConstantExpr::getIntToPtr(MapAddr, PointerType::getUnqual(Int8Ty));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
|
ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
|
||||||
ConstantInt *One = ConstantInt::get(Int8Ty, 1);
|
ConstantInt *One = ConstantInt::get(Int8Ty, 1);
|
||||||
|
|
||||||
@ -581,10 +636,20 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
/* Load SHM pointer */
|
/* Load SHM pointer */
|
||||||
|
|
||||||
|
Value *MapPtrIdx;
|
||||||
|
|
||||||
|
if (map_addr) {
|
||||||
|
|
||||||
|
MapPtrIdx = IRB.CreateGEP(MapPtrFixed, CurLoc);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
|
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
|
||||||
MapPtr->setMetadata(M.getMDKindID("nosanitize"),
|
MapPtr->setMetadata(M.getMDKindID("nosanitize"),
|
||||||
MDNode::get(C, None));
|
MDNode::get(C, None));
|
||||||
Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
|
MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Update bitmap */
|
/* Update bitmap */
|
||||||
|
|
||||||
@ -629,7 +694,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL || dictionary.size()) {
|
if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) {
|
||||||
|
|
||||||
// yes we could create our own function, insert it into ctors ...
|
// yes we could create our own function, insert it into ctors ...
|
||||||
// but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
|
// but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
|
||||||
@ -658,6 +723,18 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
BasicBlock::iterator IP = bb->getFirstInsertionPt();
|
BasicBlock::iterator IP = bb->getFirstInsertionPt();
|
||||||
IRBuilder<> IRB(&(*IP));
|
IRBuilder<> IRB(&(*IP));
|
||||||
|
|
||||||
|
if (map_addr) {
|
||||||
|
|
||||||
|
GlobalVariable *AFLMapAddrFixed = new GlobalVariable(
|
||||||
|
M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr",
|
||||||
|
0, GlobalVariable::GeneralDynamicTLSModel, 0, false);
|
||||||
|
ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
|
||||||
|
StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
|
||||||
|
StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"),
|
||||||
|
MDNode::get(C, None));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) {
|
if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) {
|
||||||
|
|
||||||
uint32_t write_loc = afl_global_id;
|
uint32_t write_loc = afl_global_id;
|
||||||
|
@ -52,6 +52,10 @@
|
|||||||
|
|
||||||
#define CONST_PRIO 5
|
#define CONST_PRIO 5
|
||||||
|
|
||||||
|
//#ifndef MAP_FIXED_NOREPLACE
|
||||||
|
//#define MAP_FIXED_NOREPLACE MAP_FIXED
|
||||||
|
//#endif
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
@ -69,12 +73,14 @@ u32 __afl_final_loc;
|
|||||||
u32 __afl_prev_ctx;
|
u32 __afl_prev_ctx;
|
||||||
u32 __afl_cmp_counter;
|
u32 __afl_cmp_counter;
|
||||||
u32 __afl_dictionary_len;
|
u32 __afl_dictionary_len;
|
||||||
|
u64 __afl_map_addr;
|
||||||
#else
|
#else
|
||||||
__thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
|
__thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
|
||||||
__thread u32 __afl_final_loc;
|
__thread u32 __afl_final_loc;
|
||||||
__thread u32 __afl_prev_ctx;
|
__thread u32 __afl_prev_ctx;
|
||||||
__thread u32 __afl_cmp_counter;
|
__thread u32 __afl_cmp_counter;
|
||||||
__thread u32 __afl_dictionary_len;
|
__thread u32 __afl_dictionary_len;
|
||||||
|
__thread u64 __afl_map_addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct cmp_map *__afl_cmp_map;
|
struct cmp_map *__afl_cmp_map;
|
||||||
@ -88,6 +94,10 @@ static u8 is_persistent;
|
|||||||
static void __afl_map_shm(void) {
|
static void __afl_map_shm(void) {
|
||||||
|
|
||||||
u8 * id_str = getenv(SHM_ENV_VAR);
|
u8 * id_str = getenv(SHM_ENV_VAR);
|
||||||
|
unsigned int map_size = MAP_SIZE;
|
||||||
|
|
||||||
|
if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE)
|
||||||
|
map_size = __afl_final_loc;
|
||||||
|
|
||||||
/* If we're running under AFL, attach to the appropriate region, replacing the
|
/* If we're running under AFL, attach to the appropriate region, replacing the
|
||||||
early-stage __afl_area_initial region that is needed to allow some really
|
early-stage __afl_area_initial region that is needed to allow some really
|
||||||
@ -99,10 +109,6 @@ static void __afl_map_shm(void) {
|
|||||||
const char * shm_file_path = id_str;
|
const char * shm_file_path = id_str;
|
||||||
int shm_fd = -1;
|
int shm_fd = -1;
|
||||||
unsigned char *shm_base = NULL;
|
unsigned char *shm_base = NULL;
|
||||||
unsigned int map_size = MAP_SIZE
|
|
||||||
|
|
||||||
if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE) map_size =
|
|
||||||
__afl_final_loc;
|
|
||||||
|
|
||||||
/* create the shared memory segment as if it was a file */
|
/* create the shared memory segment as if it was a file */
|
||||||
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
|
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
|
||||||
@ -114,7 +120,18 @@ static void __afl_map_shm(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* map the shared memory segment to the address space of the process */
|
/* map the shared memory segment to the address space of the process */
|
||||||
shm_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
if (__afl_map_addr) {
|
||||||
|
|
||||||
|
shm_base = mmap((void *)__afl_map_addr, map_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_FIXED | MAP_SHARED, shm_fd, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
shm_base =
|
||||||
|
mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (shm_base == MAP_FAILED) {
|
if (shm_base == MAP_FAILED) {
|
||||||
|
|
||||||
close(shm_fd);
|
close(shm_fd);
|
||||||
@ -129,7 +146,8 @@ static void __afl_map_shm(void) {
|
|||||||
#else
|
#else
|
||||||
u32 shm_id = atoi(id_str);
|
u32 shm_id = atoi(id_str);
|
||||||
|
|
||||||
__afl_area_ptr = shmat(shm_id, NULL, 0);
|
__afl_area_ptr = shmat(shm_id, (void *)__afl_map_addr, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Whooooops. */
|
/* Whooooops. */
|
||||||
@ -141,6 +159,19 @@ static void __afl_map_shm(void) {
|
|||||||
|
|
||||||
__afl_area_ptr[0] = 1;
|
__afl_area_ptr[0] = 1;
|
||||||
|
|
||||||
|
} else if (__afl_map_addr) {
|
||||||
|
|
||||||
|
__afl_area_ptr =
|
||||||
|
mmap((void *)__afl_map_addr, map_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (__afl_area_ptr == MAP_FAILED) {
|
||||||
|
|
||||||
|
fprintf(stderr, "can not aquire mmap for address %p\n",
|
||||||
|
(void *)__afl_map_addr);
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id_str = getenv(CMPLOG_SHM_ENV_VAR);
|
id_str = getenv(CMPLOG_SHM_ENV_VAR);
|
||||||
|
@ -67,10 +67,11 @@ char *afl_environment_variables[] = {
|
|||||||
"AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
|
"AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
|
||||||
"AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
|
"AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
|
||||||
"AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES",
|
"AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES",
|
||||||
"AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO",
|
"AFL_LLVM_MAP_ADDR", "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE",
|
||||||
"AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID",
|
"AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST",
|
||||||
"AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
|
"AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID",
|
||||||
"AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
|
"AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV",
|
||||||
|
"AFL_NO_UI", "AFL_NO_PYTHON",
|
||||||
"AFL_NO_X86", // not really an env but we dont want to warn on it
|
"AFL_NO_X86", // not really an env but we dont want to warn on it
|
||||||
"AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
|
"AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
|
||||||
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
|
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
|
||||||
|
@ -127,8 +127,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* map the shared memory segment to the address space of the process */
|
/* map the shared memory segment to the address space of the process */
|
||||||
shm->map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
shm->map =
|
||||||
shm->g_shm_fd, 0);
|
mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->g_shm_fd, 0);
|
||||||
if (shm->map == MAP_FAILED) {
|
if (shm->map == MAP_FAILED) {
|
||||||
|
|
||||||
close(shm->g_shm_fd);
|
close(shm->g_shm_fd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user