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

Helge Deller <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
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;
> +        } else if (offset + len > sb.st_size) {
> +            /*
> +             * A portion of the map is beyond the end of the file.
> +             * Truncate the file portion of the allocation.
> +             */
> +            len = sb.st_size - offset;
> +            len = len + host_page_size - 1;
> +            len /= host_page_size;
> +            len *= host_page_size;
> +        }
> +    }
> +
>       if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
>           want_p = g2h_untagged(start);
>       }
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.