Skip to content

mremap fails with EFAULT if address range overlaps with stack guard

This issue was actually reported earlier and a patch was purposed: https://patchwork.kernel.org/project/qemu-devel/patch/20200305210534.28392-1-tobias.koch@nonterra.com/

However, it seems the patch was abandoned due to undesirable implementation details. I hope this issue can get another look and fixed.


Host environment

  • Operating system: any linux
  • OS/kernel version: any kernel version
  • Architecture: x86_64
  • QEMU flavor: qemu-user-static (ARM 32-bit)
  • QEMU version: any version
  • QEMU command line:

Emulated/Virtualized environment

  • Operating system: alpine-linux
  • OS/kernel version: host kernel (qemu-user-static)
  • Architecture: ARM 32-bit

Description of problem

When running 32-bit user-static on 64-bit host, mremap behave differently from the kernel. This difference let programs that call pthread_getattr_np on musl-libc to run into a loop on repeated calling mremap.

https://git.musl-libc.org/cgit/musl/plain/src/thread/pthread_getattr_np.c

		while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
			l += PAGE_SIZE;

Steps to reproduce

Compile the following program against musl-libc arm 32-bit, and run it in qemu-user-static on x86_64 host.

#define _GNU_SOURCE
#include <pthread.h>

int main(int argc, char *argv[]) {
	pthread_attr_t attr;
	return pthread_getattr_np(pthread_self(), &attr);
}

For example, on x86_64 fedora 38 with podman and qemu-user-static installed, we can reproduce this with alpine container:

$ podman run --rm -it --arch arm/v7 docker.io/library/alpine:latest

/ # apk add alpine-sdk

......

/ # cat test.c
#define _GNU_SOURCE
#include <pthread.h>

int main(int argc, char *argv[]) {
	pthread_attr_t attr;
	return pthread_getattr_np(pthread_self(), &attr);
}

/ # gcc test.c

/ # ./a.out

Additional information

Original thread on musl mail list where this was initially reported: https://www.openwall.com/lists/musl/2017/06/15/9

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information