mirror of
https://github.com/reactos/syzkaller.git
synced 2024-10-07 09:03:28 +00:00
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.
This commit is contained in:
parent
40723a067e
commit
f810d08444
@ -116,8 +116,14 @@ __thread jmp_buf segv_env;
|
||||
|
||||
static void segv_handler(int sig, siginfo_t* info, void* uctx)
|
||||
{
|
||||
if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
|
||||
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 (;;) {
|
||||
}
|
||||
@ -711,7 +717,7 @@ static uintptr_t syz_kvm_setup_cpu(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin
|
||||
(void)text_count;
|
||||
int text_type = 0;
|
||||
const void* text = 0;
|
||||
int text_size = 0;
|
||||
uintptr_t text_size = 0;
|
||||
NONFAILING(text_type = text_array_ptr[0].typ);
|
||||
NONFAILING(text = text_array_ptr[0].text);
|
||||
NONFAILING(text_size = text_array_ptr[0].size);
|
||||
|
@ -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 (;;) {
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ static uintptr_t syz_kvm_setup_cpu(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin
|
||||
(void)text_count; // fuzzer can spoof count and we need just 1 text, so ignore text_count
|
||||
int text_type = 0;
|
||||
const void* text = 0;
|
||||
int text_size = 0;
|
||||
uintptr_t text_size = 0;
|
||||
NONFAILING(text_type = text_array_ptr[0].typ);
|
||||
NONFAILING(text = text_array_ptr[0].text);
|
||||
NONFAILING(text_size = text_array_ptr[0].size);
|
||||
|
@ -139,7 +139,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
||||
if (mmap(&input_data[0], kMaxInput, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
|
||||
if (mmap(&input_data[0], kMaxInput, PROT_READ, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
|
||||
fail("mmap of input file failed");
|
||||
if (mmap(&output_data[0], kMaxOutput, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, kOutFd, 0) != &output_data[0])
|
||||
fail("mmap of output file failed");
|
||||
|
Loading…
Reference in New Issue
Block a user