Commit 17e2377abf16c3951d7d34521ceade4d7dc31d01

Authored by pbrook
1 parent 82e671d9

Prevent guest reusing host memory allocations.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4710 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -39,7 +39,7 @@ recurse-all: $(SUBDIR_RULES) @@ -39,7 +39,7 @@ recurse-all: $(SUBDIR_RULES)
39 ####################################################################### 39 #######################################################################
40 # BLOCK_OBJS is code used by both qemu system emulation and qemu-img 40 # BLOCK_OBJS is code used by both qemu system emulation and qemu-img
41 41
42 -BLOCK_OBJS=cutils.o 42 +BLOCK_OBJS=cutils.o qemu-malloc.o
43 BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o 43 BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
44 BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o 44 BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
45 BLOCK_OBJS+=block-qcow2.o block-parallels.o 45 BLOCK_OBJS+=block-qcow2.o block-parallels.o
Makefile.target
@@ -387,7 +387,7 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH)el.ld @@ -387,7 +387,7 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH)el.ld
387 endif 387 endif
388 endif 388 endif
389 389
390 -OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \ 390 +OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \
391 elfload.o linuxload.o uaccess.o 391 elfload.o linuxload.o uaccess.o
392 LIBS+= $(AIOLIBS) 392 LIBS+= $(AIOLIBS)
393 ifdef TARGET_HAS_BFLT 393 ifdef TARGET_HAS_BFLT
@@ -444,7 +444,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000 @@ -444,7 +444,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000
444 444
445 LIBS+=-lmx 445 LIBS+=-lmx
446 446
447 -OBJS= main.o commpage.o machload.o mmap.o osdep.o signal.o syscall.o thunk.o 447 +OBJS= main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o
448 448
449 OBJS+= libqemu.a 449 OBJS+= libqemu.a
450 450
cutils.c
@@ -95,38 +95,3 @@ time_t mktimegm(struct tm *tm) @@ -95,38 +95,3 @@ time_t mktimegm(struct tm *tm)
95 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; 95 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
96 return t; 96 return t;
97 } 97 }
98 -  
99 -void *get_mmap_addr(unsigned long size)  
100 -{  
101 - return NULL;  
102 -}  
103 -  
104 -void qemu_free(void *ptr)  
105 -{  
106 - free(ptr);  
107 -}  
108 -  
109 -void *qemu_malloc(size_t size)  
110 -{  
111 - return malloc(size);  
112 -}  
113 -  
114 -void *qemu_mallocz(size_t size)  
115 -{  
116 - void *ptr;  
117 - ptr = qemu_malloc(size);  
118 - if (!ptr)  
119 - return NULL;  
120 - memset(ptr, 0, size);  
121 - return ptr;  
122 -}  
123 -  
124 -char *qemu_strdup(const char *str)  
125 -{  
126 - char *ptr;  
127 - ptr = qemu_malloc(strlen(str) + 1);  
128 - if (!ptr)  
129 - return NULL;  
130 - strcpy(ptr, str);  
131 - return ptr;  
132 -}  
@@ -263,13 +263,33 @@ static inline PageDesc *page_find_alloc(target_ulong index) @@ -263,13 +263,33 @@ static inline PageDesc *page_find_alloc(target_ulong index)
263 { 263 {
264 PageDesc **lp, *p; 264 PageDesc **lp, *p;
265 265
  266 +#if TARGET_LONG_BITS > 32
  267 + /* Host memory outside guest VM. For 32-bit targets we have already
  268 + excluded high addresses. */
  269 + if (index > ((target_ulong)L2_SIZE * L1_SIZE * TARGET_PAGE_SIZE))
  270 + return NULL;
  271 +#endif
266 lp = &l1_map[index >> L2_BITS]; 272 lp = &l1_map[index >> L2_BITS];
267 p = *lp; 273 p = *lp;
268 if (!p) { 274 if (!p) {
269 /* allocate if not found */ 275 /* allocate if not found */
270 - p = qemu_malloc(sizeof(PageDesc) * L2_SIZE);  
271 - memset(p, 0, sizeof(PageDesc) * L2_SIZE); 276 +#if defined(CONFIG_USER_ONLY)
  277 + unsigned long addr;
  278 + size_t len = sizeof(PageDesc) * L2_SIZE;
  279 + /* Don't use qemu_malloc because it may recurse. */
  280 + p = mmap(0, len, PROT_READ | PROT_WRITE,
  281 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  282 + *lp = p;
  283 + addr = h2g(p);
  284 + if (addr == (target_ulong)addr) {
  285 + page_set_flags(addr & TARGET_PAGE_MASK,
  286 + TARGET_PAGE_ALIGN(addr + len),
  287 + PAGE_RESERVED);
  288 + }
  289 +#else
  290 + p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE);
272 *lp = p; 291 *lp = p;
  292 +#endif
273 } 293 }
274 return p + (index & (L2_SIZE - 1)); 294 return p + (index & (L2_SIZE - 1));
275 } 295 }
@@ -1912,6 +1932,10 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) @@ -1912,6 +1932,10 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
1912 flags |= PAGE_WRITE_ORG; 1932 flags |= PAGE_WRITE_ORG;
1913 for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { 1933 for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1914 p = page_find_alloc(addr >> TARGET_PAGE_BITS); 1934 p = page_find_alloc(addr >> TARGET_PAGE_BITS);
  1935 + /* We may be called for host regions that are outside guest
  1936 + address space. */
  1937 + if (!p)
  1938 + return;
1915 /* if the write protection is set, then we invalidate the code 1939 /* if the write protection is set, then we invalidate the code
1916 inside */ 1940 inside */
1917 if (!(p->flags & PAGE_WRITE) && 1941 if (!(p->flags & PAGE_WRITE) &&
linux-user/mmap.c
@@ -73,6 +73,52 @@ void mmap_unlock(void) @@ -73,6 +73,52 @@ void mmap_unlock(void)
73 } 73 }
74 #endif 74 #endif
75 75
  76 +void *qemu_vmalloc(size_t size)
  77 +{
  78 + void *p;
  79 + unsigned long addr;
  80 + mmap_lock();
  81 + /* Use map and mark the pages as used. */
  82 + p = mmap(NULL, size, PROT_READ | PROT_WRITE,
  83 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  84 +
  85 + addr = (unsigned long)p;
  86 + if (addr == (target_ulong) addr) {
  87 + /* Allocated region overlaps guest address space.
  88 + This may recurse. */
  89 + page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),
  90 + PAGE_RESERVED);
  91 + }
  92 +
  93 + mmap_unlock();
  94 + return p;
  95 +}
  96 +
  97 +void *qemu_malloc(size_t size)
  98 +{
  99 + char * p;
  100 + size += 16;
  101 + p = qemu_vmalloc(size);
  102 + *(size_t *)p = size;
  103 + return p + 16;
  104 +}
  105 +
  106 +/* We use map, which is always zero initialized. */
  107 +void * qemu_mallocz(size_t size)
  108 +{
  109 + return qemu_malloc(size);
  110 +}
  111 +
  112 +void qemu_free(void *ptr)
  113 +{
  114 + /* FIXME: We should unmark the reserved pages here. However this gets
  115 + complicated when one target page spans multiple host pages, so we
  116 + don't bother. */
  117 + size_t *p;
  118 + p = (size_t *)((char *)ptr - 16);
  119 + munmap(p, *p);
  120 +}
  121 +
76 /* NOTE: all the constants are the HOST ones, but addresses are target. */ 122 /* NOTE: all the constants are the HOST ones, but addresses are target. */
77 int target_mprotect(abi_ulong start, abi_ulong len, int prot) 123 int target_mprotect(abi_ulong start, abi_ulong len, int prot)
78 { 124 {
qemu-malloc.c 0 → 100644
  1 +/*
  2 + * malloc-like functions for system emulation.
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "qemu-common.h"
  25 +
  26 +void *get_mmap_addr(unsigned long size)
  27 +{
  28 + return NULL;
  29 +}
  30 +
  31 +void qemu_free(void *ptr)
  32 +{
  33 + free(ptr);
  34 +}
  35 +
  36 +void *qemu_malloc(size_t size)
  37 +{
  38 + return malloc(size);
  39 +}
  40 +
  41 +void *qemu_mallocz(size_t size)
  42 +{
  43 + void *ptr;
  44 + ptr = qemu_malloc(size);
  45 + if (!ptr)
  46 + return NULL;
  47 + memset(ptr, 0, size);
  48 + return ptr;
  49 +}
  50 +
  51 +char *qemu_strdup(const char *str)
  52 +{
  53 + char *ptr;
  54 + ptr = qemu_malloc(strlen(str) + 1);
  55 + if (!ptr)
  56 + return NULL;
  57 + strcpy(ptr, str);
  58 + return ptr;
  59 +}