From dd56621bbb2f7137b065b5af1c13c227652416ad Mon Sep 17 00:00:00 2001 From: coco Date: Wed, 21 Oct 2015 22:25:49 +0200 Subject: [PATCH] fix for use after free in case of double unmap --- tests/regress/Makefile | 1 + tests/regress/mem_double_unmap.c | 51 ++++++++++++++++++++++++++++++++ uc.c | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/regress/mem_double_unmap.c diff --git a/tests/regress/Makefile b/tests/regress/Makefile index e03c27e..49010eb 100644 --- a/tests/regress/Makefile +++ b/tests/regress/Makefile @@ -8,6 +8,7 @@ TESTS += ro_mem_test nr_mem_test TESTS += timeout_segfault TESTS += rep_movsb TESTS += mem_unmap +TESTS += mem_double_unmap TESTS += mem_protect TESTS += mem_exec diff --git a/tests/regress/mem_double_unmap.c b/tests/regress/mem_double_unmap.c new file mode 100644 index 0000000..9508671 --- /dev/null +++ b/tests/regress/mem_double_unmap.c @@ -0,0 +1,51 @@ +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv, char **envp) +{ + uc_engine *uc; + uc_hook trace1, trace2; + uc_err err; + + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); + if (err) { + printf("not ok - Failed on uc_open() with error returned: %u\n", err); + return; + } + + uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); + if (err) { + printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); + return; + } + + uc_mem_map(uc, 0x4000, 0x1000, UC_PROT_ALL); + if (err) { + printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); + return; + } + + err = uc_mem_unmap(uc, 0x4000, 0x1000); + if (err) { + printf("not ok - Failed on uc_mem_unmap() with error returned: %u\n", err); + return; + } + + err = uc_mem_unmap(uc, 0x4000, 0x1000); + if (!err) { + printf("not ok - second unmap succeeded\n"); + return 1; + } + + printf("Tests OK\n"); + uc_close(uc); + return 0; +} diff --git a/uc.c b/uc.c index 94ac155..02c157b 100644 --- a/uc.c +++ b/uc.c @@ -814,7 +814,7 @@ MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address) // try with the cache index first i = uc->mapped_block_cache_index; - if (address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) + if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) return uc->mapped_blocks[i]; for(i = 0; i < uc->mapped_block_count; i++) {