From f810d0844478c385985e2d0fe0a6a603a7b1c8bd Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 25 Jan 2017 11:01:30 +0100 Subject: executor: protect against memory corruptions better Fuzzer has figured out how to corrupt input/output shmem regions abusing the text memcpy in syz_kvm_setup_cpu. It guessed a negative text_size value that causes the memcpy to overwrite shmem regions. Protect better against such cases: 1. Make text_size unsigned (there is already a check that it is less than 1000). 2. Map input region as readable only, we don't write to it. 3. Add address sanity check to segv_handler, if we see that we are writing into executable data, it's better to crash instantly. --- executor/common.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'executor/common.h') diff --git a/executor/common.h b/executor/common.h index 987cad84f..10b3ea5bf 100644 --- a/executor/common.h +++ b/executor/common.h @@ -132,8 +132,20 @@ __thread jmp_buf segv_env; static void segv_handler(int sig, siginfo_t* info, void* uctx) { - if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED)) + // Generated programs can contain bad (unmapped/protected) addresses, + // which cause SIGSEGVs during copyin/copyout. + // This handler ignores such crashes to allow the program to proceed. + // We additionally opportunistically check that the faulty address + // is not within executable data region, because such accesses can corrupt + // output region and then fuzzer will fail on corrupted data. + uintptr_t addr = (uintptr_t)info->si_addr; + const uintptr_t prog_start = 1 << 20; + const uintptr_t prog_end = 100 << 20; + if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) { + debug("SIGSEGV on %p, skipping\n", addr); _longjmp(segv_env, 1); + } + debug("SIGSEGV on %p, exiting\n", addr); doexit(sig); for (;;) { } -- cgit mrf-deployment