From: Mark Wielaard Date: Tue, 15 Jul 2025 21:49:36 +0000 (+0200) Subject: Support mmap MAP_FIXED_NOREPLACE if defined X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cad20f3e7d42e6371896e2492f0fc3a081314238;p=thirdparty%2Fvalgrind.git Support mmap MAP_FIXED_NOREPLACE if defined Define VKI_MAP_FIXED_NOREPLACE for amd64-linux, arm-linux, arm64-linux, mips32-linux, mips64-linux, riscv64-linux and x86-linux. If it is defined then ML_(generic_PRE_sys_mmap) will also interpret VKI_MAP_FIXED_NOREPLACE as an MFixed hint. If the aspace manager doesn't find a MAP_FIXED_NOREPLACE ok, then fail with EEXIST. If the actual kernel mmap request fails and MAP_FIXED_NOREPLACE is set also immediately fail with EEXIST without retrying. This fixes the LTP mmap17 testcase. https://bugs.kde.org/show_bug.cgi?id=418756 --- diff --git a/NEWS b/NEWS index 49403da01..796d9716e 100644 --- a/NEWS +++ b/NEWS @@ -29,8 +29,8 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. -506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 338803 Handling of dwz debug alt files or cross-CU is broken +418756 MAP_FIXED_NOREPLACE mmap flag unsupported 493434 Add --track-fds=bad mode (no "leak" tracking) 503098 Incorrect NAN-boxing for float registers in RISC-V 503641 close_range syscalls started failing with 3.25.0 @@ -52,6 +52,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. AMD64_GET_TLSBASE 505228 Wrap linux specific mseal syscall 502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) +506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic 506930 valgrind allows SIGKILL being reset to SIG_DFL diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 50deb1e76..50415a2fa 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2678,7 +2678,12 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, (fixed/hint/any), and ask aspacem what we should do. */ mreq.start = arg1; mreq.len = arg2; - if (arg4 & VKI_MAP_FIXED) { + if ((arg4 & VKI_MAP_FIXED) +#if defined(VKI_MAP_FIXED_NOREPLACE) + || (arg4 & VKI_MAP_FIXED_NOREPLACE) +#endif + ) + { mreq.rkind = MFixed; } else #if defined(VGO_solaris) && defined(VKI_MAP_ALIGN) @@ -2710,6 +2715,11 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); if (!mreq_ok) { /* Our request was bounced, so we'd better fail. */ +#if defined(VKI_MAP_FIXED_NOREPLACE) + if (arg4 & VKI_MAP_FIXED_NOREPLACE) { + return VG_(mk_SysRes_Error)( VKI_EEXIST ); + } +#endif return VG_(mk_SysRes_Error)( VKI_EINVAL ); } @@ -2744,6 +2754,13 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, } # endif +# if defined(VKI_MAP_FIXED_NOREPLACE) + /* FIXED_NOREPLACE is fatal, no retries. */ + if ((arg4 & VKI_MAP_FIXED_NOREPLACE) && sr_isError(sres)) { + return VG_(mk_SysRes_Error)( VKI_EEXIST ); + } +# endif + /* A refinement: it may be that the kernel refused aspacem's choice of address. If we were originally asked for a hinted mapping, there is still a last chance: try again at any address. diff --git a/include/vki/vki-amd64-linux.h b/include/vki/vki-amd64-linux.h index 12cd65ac7..bbcf4ab4e 100644 --- a/include/vki/vki-amd64-linux.h +++ b/include/vki/vki-amd64-linux.h @@ -236,6 +236,7 @@ struct vki_sigcontext { #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_32BIT 0x40 /* only give out 32bit addresses */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.9/include/asm-x86_64/fcntl.h diff --git a/include/vki/vki-arm-linux.h b/include/vki/vki-arm-linux.h index 7e0001c0c..a72268ca4 100644 --- a/include/vki/vki-arm-linux.h +++ b/include/vki/vki-arm-linux.h @@ -233,6 +233,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-i386/fcntl.h diff --git a/include/vki/vki-arm64-linux.h b/include/vki/vki-arm64-linux.h index 2fc97e614..1b005c775 100644 --- a/include/vki/vki-arm64-linux.h +++ b/include/vki/vki-arm64-linux.h @@ -215,6 +215,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-3.10.5/uapi/include/asm-generic/fcntl.h diff --git a/include/vki/vki-mips32-linux.h b/include/vki/vki-mips32-linux.h index 2d752e2cc..584b5dd72 100644 --- a/include/vki/vki-mips32-linux.h +++ b/include/vki/vki-mips32-linux.h @@ -300,6 +300,7 @@ struct vki_sigcontext { #define VKI_MAP_LOCKED 0x8000 /* pages are locked */ #define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ #define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- diff --git a/include/vki/vki-mips64-linux.h b/include/vki/vki-mips64-linux.h index 527b0dae6..9171b6fb0 100644 --- a/include/vki/vki-mips64-linux.h +++ b/include/vki/vki-mips64-linux.h @@ -306,6 +306,7 @@ struct vki_sigcontext { #define VKI_MAP_LOCKED 0x8000 /* pages are locked */ #define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ #define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.35.9/include/asm-mips/fcntl.h diff --git a/include/vki/vki-riscv64-linux.h b/include/vki/vki-riscv64-linux.h index 5cc98b6ab..0ad826c02 100644 --- a/include/vki/vki-riscv64-linux.h +++ b/include/vki/vki-riscv64-linux.h @@ -186,6 +186,7 @@ typedef struct vki_sigaltstack { //---------------------------------------------------------------------- #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-6.0/include/uapi/linux/mman.h diff --git a/include/vki/vki-x86-linux.h b/include/vki/vki-x86-linux.h index 5a5f9e5d8..d00de22b4 100644 --- a/include/vki/vki-x86-linux.h +++ b/include/vki/vki-x86-linux.h @@ -271,6 +271,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-i386/fcntl.h