Re: [PATCH] linux-user: fix issues with mmap on 4K guest on 16K host and library load

Richard Henderson <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
On 8/7/26 14:26, Helge Deller wrote:
> On 8/5/26 18:40, Andreas Kemnade wrote:
>> Strace in qemu:
>> 198005 openat(AT_FDCWD,"/lib/arm-linux-gnueabihf/libselinux.so.1",O_RDONLY|O_LARGEFILE| 
>> O_CLOEXEC) = 3
>> 198005 read(3,0x40802570,512) = 512
>> 198005 statx(3,"",AT_EMPTY_PATH|AT_NO_AUTOMOUNT| 
>> AT_STATX_SYNC_AS_STAT,STATX_BASIC_STATS,0x408022a8) = 0
>> 198005 mmap2(NULL,269428,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE,-1,0) = 
>> 0x40868000
>> 198005 mmap2(0x40870000,203892,PROT_EXEC|PROT_READ,MAP_PRIVATE|MAP_DENYWRITE| 
>> MAP_FIXED,3,0) = 0x40870000
>> 198005 munmap(0x40868000,32768) = 0
>> 198005 munmap(0x408a2000,31860) = 0
>> 198005 mprotect(0x40890000,61440,PROT_NONE) = 0
>> 198005 mmap2(0x4089f000,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_DENYWRITE| 
>> MAP_FIXED,3,0x1f) = -1 errno=14 (Bad address)
>>
>> strace outside qemu:
>> [pid 195331] readlinkat(AT_FDCWD, "/usr/lib", 0x7fffd1a7fd00, 1023) = -1 EINVAL (Invalid 
>> argument)
>> [pid 195331] readlinkat(AT_FDCWD, "/usr/lib/arm-linux-gnueabihf", 0x7fffd1a7fd00, 1023) 
>> = -1 EINVAL (Invalid argument)
>> [pid 195331] readlinkat(AT_FDCWD, "/usr/lib/arm-linux-gnueabihf/libselinux.so.1", 
>> 0x7fffd1a7fd00, 1023) = -1 EINVAL (Invalid argument)
>> [pid 195331] faccessat(AT_FDCWD, "/usr/gnemul/qemu-arm/lib/arm-linux-gnueabihf/ 
>> libselinux.so.1", F_OK) = -1 ENOENT (No such file or directory)
>> [pid 195331] openat(AT_FDCWD, "/lib/arm-linux-gnueabihf/libselinux.so.1", O_RDONLY| 
>> O_CLOEXEC) = 3
>> [pid 195331] read(3, 
>> "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\0\0\0\0004\0\0\0"..., 512) = 512
>> [pid 195331] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, 
>> STATX_BASIC_STATS, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, 
>> stx_mode=S_IFREG|0644, stx_size=132612, ...}) = 0
>> [pid 195331] mmap(0x408a8000, 16384, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS| 
>> MAP_DENYWRITE, -1, 0) = 0x408a8000
>> [pid 195331] mprotect(0x408a8000, 16384, PROT_WRITE) = 0
>> [pid 195331] mprotect(0x408a8000, 16384, PROT_NONE) = 0
>> [pid 195331] mmap(0x40868000, 262144, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS| 
>> MAP_DENYWRITE, -1, 0) = 0x40868000
>> [pid 195331] mprotect(0x408a0000, 16384, PROT_WRITE) = 0
>> [pid 195331] pread64(3, "", 8192, 196608) = 0
>> [pid 195331] mprotect(0x408a0000, 16384, PROT_READ) = 0
>> [pid 195331] mmap(0x40870000, 196608, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 
>> 0) = 0x40870000
>> [pid 195331] mmap(0x40868000, 32768, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS| 
>> MAP_NORESERVE, -1, 0) = 0x40868000
>> [pid 195331] mmap(0x408a4000, 32768, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS| 
>> MAP_NORESERVE, -1, 0) = 0x408a4000
>> [pid 195331] mprotect(0x4089c000, 16384, PROT_READ) = 0
>> [pid 195331] mprotect(0x40890000, 49152, PROT_NONE) = 0
>> [pid 195331] mprotect(0x4089c000, 16384, PROT_WRITE) = 0
>> [pid 195331] pread64(3, 0x4089f000, 4096, 126976) = -1 EFAULT (Bad address)
>>
>> That makes simple commands like ls --version to fail.
>> Tested was arm32 on a arm64 only host.
>>
>> Fix that issue by truncating file mapping and replacing out-of-file
>> mappings by anonymous mappings.
> 
> Could you please explain "the issue" and not just referring to the strace?
> It's not that easy to see the problem.
> 
> Thanks!
> Helge
> 
> Btw: you patch might fix this problem, but you may run into other problems too,
> see e.g.: https://gitlab.com/qemu-project/qemu/-/work_items/3410
> 
> 
>> Signed-off-by: Andreas Kemnade <[email protected]>
>> ---
>>   linux-user/mmap.c | 26 ++++++++++++++++++++++++++
>>   1 file changed, 26 insertions(+)
>>
>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
>> index 423c77856a..4fce6fae3c 100644
>> --- a/linux-user/mmap.c
>> +++ b/linux-user/mmap.c
>> @@ -796,6 +796,32 @@ static abi_long mmap_h_gt_g(abi_ulong start, abi_ulong len,
>>       bool misaligned_offset = false;
>>       size_t host_len;
>> +    if (!(flags & MAP_ANONYMOUS)) {
>> +        struct stat sb;
>> +
>> +        if (fstat(fd, &sb) == -1) {
>> +            return -1;
>> +        }
>> +        if (offset >= sb.st_size) {
>> +            /*
>> +             * The entire map is beyond the end of the file.
>> +             * Transform it to an anonymous mapping.
>> +             */
>> +            flags |= MAP_ANONYMOUS;
>> +            fd = -1;
>> +            offset = 0;

This is incorrect.  Even natively, accessing past the end of the file should SIGBUS.
For host page size > guest page size, as we are here, you should never encounter that 
particular emulation problem.

I've no idea what you're trying to solve.


r~
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.