diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-09 13:47:45 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-09 13:47:45 +0000 |
commit | 17e2377abf16c3951d7d34521ceade4d7dc31d01 (patch) | |
tree | c6e540f435401b092933145541df335748b5fd58 /linux-user/mmap.c | |
parent | 82e671d9ecdf1422780e56182e9c228071493a22 (diff) |
Prevent guest reusing host memory allocations.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4710 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r-- | linux-user/mmap.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c index b4ca1074b3..be1ddb9f25 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -73,6 +73,52 @@ void mmap_unlock(void) } #endif +void *qemu_vmalloc(size_t size) +{ + void *p; + unsigned long addr; + mmap_lock(); + /* Use map and mark the pages as used. */ + p = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + addr = (unsigned long)p; + if (addr == (target_ulong) addr) { + /* Allocated region overlaps guest address space. + This may recurse. */ + page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size), + PAGE_RESERVED); + } + + mmap_unlock(); + return p; +} + +void *qemu_malloc(size_t size) +{ + char * p; + size += 16; + p = qemu_vmalloc(size); + *(size_t *)p = size; + return p + 16; +} + +/* We use map, which is always zero initialized. */ +void * qemu_mallocz(size_t size) +{ + return qemu_malloc(size); +} + +void qemu_free(void *ptr) +{ + /* FIXME: We should unmark the reserved pages here. However this gets + complicated when one target page spans multiple host pages, so we + don't bother. */ + size_t *p; + p = (size_t *)((char *)ptr - 16); + munmap(p, *p); +} + /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) { |