ac0bf8bd58
This was deleted in b393370212
, but was
still necessary. Without it, qemu in user mode has the wrong return
value for mremap, which leads to infinite looping in some
situations (afaik only with musl). This could be observed with
qemu-user-static when crossbuilding webkit2gtk for armv*-musl, where
strace(1) showed infinite looping:
mremap(0x6525a000, 4096, 8192, 0^C) = -1 ENOMEM (Out of memory)
The command being used was:
/usr/bin/qemu-arm-static -L /usr/arm-linux-musleabihf -E LD_LIBRARY_PATH=/usr/arm-linux-musleabihf/usr/lib:.libs: /builddir/webkitgtk-2.32.1/build/Source/WebKit/tmp-introspecth0go8pvu/WebKit2-4.0 --introspect-dump=/builddir/webkitgtk-2.32.1/build/Source/WebKit/tmp-introspecth0go8pvu/functions.txt,/builddir/webkitgtk-2.32.1/build/Source/WebKit/tmp-introspecth0go8pvu/dump.xml
42 lines
1.6 KiB
Diff
42 lines
1.6 KiB
Diff
Source: @pullmoll
|
|
Upstream: no
|
|
Reason: errno=EFAULT when the address passed to mremap(2) is not valid
|
|
|
|
See Rich Felker's comment at https://www.openwall.com/lists/musl/2017/06/21/2 for
|
|
why we need to return errno as described in man mremap(2) from qemu-user-static.
|
|
Also speed up the loop when checking for increasing the mappings size to go
|
|
in steps of TARGET_PAGE_SIZE and OR-in a check for the very last byte of the range.
|
|
diff --git linux-user/mmap.c linux-user/mmap.c
|
|
index 7e3b245..1e8d0f1 100644
|
|
--- linux-user/mmap.c
|
|
+++ linux-user/mmap.c
|
|
@@ -738,7 +738,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
|
!guest_range_valid_untagged(new_addr, new_size)) ||
|
|
((flags & MREMAP_MAYMOVE) == 0 &&
|
|
!guest_range_valid_untagged(old_addr, new_size))) {
|
|
- errno = ENOMEM;
|
|
+ errno = EFAULT;
|
|
return -1;
|
|
}
|
|
|
|
@@ -775,9 +775,10 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
|
abi_ulong addr;
|
|
for (addr = old_addr + old_size;
|
|
addr < old_addr + new_size;
|
|
- addr++) {
|
|
+ addr += TARGET_PAGE_SIZE) {
|
|
prot |= page_get_flags(addr);
|
|
}
|
|
+ prot |= page_get_flags(old_addr + new_size - 1);
|
|
}
|
|
if (prot == 0) {
|
|
host_addr = mremap(g2h_untagged(old_addr),
|
|
@@ -796,7 +797,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
|
}
|
|
}
|
|
} else {
|
|
- errno = ENOMEM;
|
|
+ errno = EFAULT;
|
|
host_addr = MAP_FAILED;
|
|
}
|
|
}
|