Commit 7ab240ad4be6cd57b0656d291a0a4a1dfc426035

Authored by balrog
1 parent 662caa6f

Teach mmap to not overwrite reserved pages and fix brk return value (Richard Purdie).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4255 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/mmap.c
@@ -259,13 +259,24 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, @@ -259,13 +259,24 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
259 host_start += offset - host_offset; 259 host_start += offset - host_offset;
260 start = h2g(host_start); 260 start = h2g(host_start);
261 } else { 261 } else {
  262 + int flg;
  263 + target_ulong addr;
  264 +
262 if (start & ~TARGET_PAGE_MASK) { 265 if (start & ~TARGET_PAGE_MASK) {
263 errno = EINVAL; 266 errno = EINVAL;
264 return -1; 267 return -1;
265 } 268 }
266 end = start + len; 269 end = start + len;
267 real_end = HOST_PAGE_ALIGN(end); 270 real_end = HOST_PAGE_ALIGN(end);
268 - 271 +
  272 + for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) {
  273 + flg = page_get_flags(addr);
  274 + if (flg & PAGE_RESERVED) {
  275 + errno = ENXIO;
  276 + return -1;
  277 + }
  278 + }
  279 +
269 /* worst case: we cannot map the file because the offset is not 280 /* worst case: we cannot map the file because the offset is not
270 aligned, so we read it */ 281 aligned, so we read it */
271 if (!(flags & MAP_ANONYMOUS) && 282 if (!(flags & MAP_ANONYMOUS) &&
linux-user/syscall.c
@@ -420,7 +420,7 @@ abi_long do_brk(abi_ulong new_brk) @@ -420,7 +420,7 @@ abi_long do_brk(abi_ulong new_brk)
420 if (!new_brk) 420 if (!new_brk)
421 return target_brk; 421 return target_brk;
422 if (new_brk < target_original_brk) 422 if (new_brk < target_original_brk)
423 - return -TARGET_ENOMEM; 423 + return target_brk;
424 424
425 brk_page = HOST_PAGE_ALIGN(target_brk); 425 brk_page = HOST_PAGE_ALIGN(target_brk);
426 426
@@ -435,12 +435,11 @@ abi_long do_brk(abi_ulong new_brk) @@ -435,12 +435,11 @@ abi_long do_brk(abi_ulong new_brk)
435 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, 435 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
436 PROT_READ|PROT_WRITE, 436 PROT_READ|PROT_WRITE,
437 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); 437 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
438 - if (is_error(mapped_addr)) {  
439 - return mapped_addr;  
440 - } else { 438 +
  439 + if (!is_error(mapped_addr))
441 target_brk = new_brk; 440 target_brk = new_brk;
442 - return target_brk;  
443 - } 441 +
  442 + return target_brk;
444 } 443 }
445 444
446 static inline abi_long copy_from_user_fdset(fd_set *fds, 445 static inline abi_long copy_from_user_fdset(fd_set *fds,