From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K5hiw-0004Wo-8O for qemu-devel@nongnu.org; Mon, 09 Jun 2008 09:47:50 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K5hiu-0004WU-Bt for qemu-devel@nongnu.org; Mon, 09 Jun 2008 09:47:48 -0400 Received: from [199.232.76.173] (port=52548 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K5hiu-0004WR-6A for qemu-devel@nongnu.org; Mon, 09 Jun 2008 09:47:48 -0400 Received: from savannah.gnu.org ([199.232.41.3]:33355 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K5hit-00030Z-RG for qemu-devel@nongnu.org; Mon, 09 Jun 2008 09:47:47 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1K5his-0003tu-RH for qemu-devel@nongnu.org; Mon, 09 Jun 2008 13:47:46 +0000 Received: from pbrook by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1K5his-0003to-IU for qemu-devel@nongnu.org; Mon, 09 Jun 2008 13:47:46 +0000 MIME-Version: 1.0 Errors-To: pbrook Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Paul Brook Message-Id: Date: Mon, 09 Jun 2008 13:47:46 +0000 Subject: [Qemu-devel] [4710] Prevent guest reusing host memory allocations. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 4710 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4710 Author: pbrook Date: 2008-06-09 13:47:45 +0000 (Mon, 09 Jun 2008) Log Message: ----------- Prevent guest reusing host memory allocations. Modified Paths: -------------- trunk/Makefile trunk/Makefile.target trunk/cutils.c trunk/exec.c trunk/linux-user/mmap.c Added Paths: ----------- trunk/qemu-malloc.c Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2008-06-09 12:10:22 UTC (rev 4709) +++ trunk/Makefile 2008-06-09 13:47:45 UTC (rev 4710) @@ -39,7 +39,7 @@ ####################################################################### # BLOCK_OBJS is code used by both qemu system emulation and qemu-img -BLOCK_OBJS=cutils.o +BLOCK_OBJS=cutils.o qemu-malloc.o BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o BLOCK_OBJS+=block-qcow2.o block-parallels.o Modified: trunk/Makefile.target =================================================================== --- trunk/Makefile.target 2008-06-09 12:10:22 UTC (rev 4709) +++ trunk/Makefile.target 2008-06-09 13:47:45 UTC (rev 4710) @@ -387,7 +387,7 @@ endif endif -OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \ +OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \ elfload.o linuxload.o uaccess.o LIBS+= $(AIOLIBS) ifdef TARGET_HAS_BFLT @@ -444,7 +444,7 @@ LIBS+=-lmx -OBJS= main.o commpage.o machload.o mmap.o osdep.o signal.o syscall.o thunk.o +OBJS= main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o OBJS+= libqemu.a Modified: trunk/cutils.c =================================================================== --- trunk/cutils.c 2008-06-09 12:10:22 UTC (rev 4709) +++ trunk/cutils.c 2008-06-09 13:47:45 UTC (rev 4710) @@ -95,38 +95,3 @@ t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; return t; } - -void *get_mmap_addr(unsigned long size) -{ - return NULL; -} - -void qemu_free(void *ptr) -{ - free(ptr); -} - -void *qemu_malloc(size_t size) -{ - return malloc(size); -} - -void *qemu_mallocz(size_t size) -{ - void *ptr; - ptr = qemu_malloc(size); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; -} - -char *qemu_strdup(const char *str) -{ - char *ptr; - ptr = qemu_malloc(strlen(str) + 1); - if (!ptr) - return NULL; - strcpy(ptr, str); - return ptr; -} Modified: trunk/exec.c =================================================================== --- trunk/exec.c 2008-06-09 12:10:22 UTC (rev 4709) +++ trunk/exec.c 2008-06-09 13:47:45 UTC (rev 4710) @@ -263,13 +263,33 @@ { PageDesc **lp, *p; +#if TARGET_LONG_BITS > 32 + /* Host memory outside guest VM. For 32-bit targets we have already + excluded high addresses. */ + if (index > ((target_ulong)L2_SIZE * L1_SIZE * TARGET_PAGE_SIZE)) + return NULL; +#endif lp = &l1_map[index >> L2_BITS]; p = *lp; if (!p) { /* allocate if not found */ - p = qemu_malloc(sizeof(PageDesc) * L2_SIZE); - memset(p, 0, sizeof(PageDesc) * L2_SIZE); +#if defined(CONFIG_USER_ONLY) + unsigned long addr; + size_t len = sizeof(PageDesc) * L2_SIZE; + /* Don't use qemu_malloc because it may recurse. */ + p = mmap(0, len, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); *lp = p; + addr = h2g(p); + if (addr == (target_ulong)addr) { + page_set_flags(addr & TARGET_PAGE_MASK, + TARGET_PAGE_ALIGN(addr + len), + PAGE_RESERVED); + } +#else + p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE); + *lp = p; +#endif } return p + (index & (L2_SIZE - 1)); } @@ -1912,6 +1932,10 @@ flags |= PAGE_WRITE_ORG; for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { p = page_find_alloc(addr >> TARGET_PAGE_BITS); + /* We may be called for host regions that are outside guest + address space. */ + if (!p) + return; /* if the write protection is set, then we invalidate the code inside */ if (!(p->flags & PAGE_WRITE) && Modified: trunk/linux-user/mmap.c =================================================================== --- trunk/linux-user/mmap.c 2008-06-09 12:10:22 UTC (rev 4709) +++ trunk/linux-user/mmap.c 2008-06-09 13:47:45 UTC (rev 4710) @@ -73,6 +73,52 @@ } #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) { Added: trunk/qemu-malloc.c =================================================================== --- trunk/qemu-malloc.c (rev 0) +++ trunk/qemu-malloc.c 2008-06-09 13:47:45 UTC (rev 4710) @@ -0,0 +1,59 @@ +/* + * malloc-like functions for system emulation. + * + * Copyright (c) 2006 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu-common.h" + +void *get_mmap_addr(unsigned long size) +{ + return NULL; +} + +void qemu_free(void *ptr) +{ + free(ptr); +} + +void *qemu_malloc(size_t size) +{ + return malloc(size); +} + +void *qemu_mallocz(size_t size) +{ + void *ptr; + ptr = qemu_malloc(size); + if (!ptr) + return NULL; + memset(ptr, 0, size); + return ptr; +} + +char *qemu_strdup(const char *str) +{ + char *ptr; + ptr = qemu_malloc(strlen(str) + 1); + if (!ptr) + return NULL; + strcpy(ptr, str); + return ptr; +}