Summary: | shmat() calls for 32-bit programs fail when running in 64-bit valgrind | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | Eric Reischer <emr150> |
Component: | memcheck | Assignee: | Julian Seward <jseward> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | anssi.hannula, gandalf, mark |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Other | ||
OS: | Linux | ||
See Also: | https://bugzilla.redhat.com/show_bug.cgi?id=1909548 | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | Patch: Fix shmat() on nanomips and x86 |
Description
Eric Reischer
2019-08-08 21:22:11 UTC
Since you are checking on RHEL6 I assume you are using a fairly old kernel. Otherwise this might be because in linux 5.0 the ipc () multiplexing syscall (as used on x86) was split into separate syscalls which aren't handled yet by valgrind: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0d6040d4681735dfc47565de288525de405a5c99 arch: add split IPC system calls where needed The IPC system call handling is highly inconsistent across architectures, some use sys_ipc, some use separate calls, and some use both. We also have some architectures that require passing IPC_64 in the flags, and others that set it implicitly. For the addition of a y2038 safe semtimedop() system call, I chose to only support the separate entry points, but that requires first supporting the regular ones with their own syscall numbers. The IPC_64 is now implied by the new semctl/shmctl/msgctl system calls even on the architectures that require passing it with the ipc() multiplexer. I'm not adding the new semtimedop() or semop() on 32-bit architectures, those will get implemented using the new semtimedop_time64() version that gets added along with the other time64 calls. Three 64-bit architectures (powerpc, s390 and sparc) get semtimedop(). Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Correct -- 2.6.32. However, RHEL7 still only uses 3.10. Perhaps (at least on Linux) we should just be using the syscall macros defined in the system-level include folders rather than carrying them around with the valgrind source? That would guarantee the binary would at least work on the distribution/release it was built on. Mark, do we need to do anything about this? Created attachment 129845 [details]
Patch: Fix shmat() on nanomips and x86
Patch attached to fix the issue. It affects all x86 and nanomips, host bitness does not matter.
There is a detailed explanation in the patch message, but the short version is that valgrind shmctl syscall variant selection was not correct.
FYI that patch resolves the bug, but it looks like it hasn't made it into the mainline branch yet. This looks similar to what is reported against Fedora arm64: https://bugzilla.redhat.com/show_bug.cgi?id=1909548 (In reply to Mark Wielaard from comment #6) > This looks similar to what is reported against Fedora arm64: > https://bugzilla.redhat.com/show_bug.cgi?id=1909548 It isn't exactly the same issue. But related. The issue in that bug is that syswrap-linux.c calls generic_PRE_sys_shmctl and generic_POST_sys_shmctl with an extra VKI_IPC_64 only for amd64_linux, but not for arm64_linux. In both cases (and riscv, but we don't have a port for that) the VKI_IPC_64 is implied. The fix for that is simply: diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 328e02a98..52074149d 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -5127,7 +5127,7 @@ PRE(sys_shmctl) PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3); PRE_REG_READ3(long, "shmctl", int, shmid, int, cmd, struct shmid_ds *, buf); -#ifdef VGP_amd64_linux +#if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3); #else ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3); @@ -5136,7 +5136,7 @@ PRE(sys_shmctl) POST(sys_shmctl) { -#ifdef VGP_amd64_linux +#if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3); #else ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); Then the generic PRE/POST do the right thing selecting the correct data structure size. Tested on x86 (32bit) and arm64 (64bit) and pushed as two separate commits: commit 889bffd9860337720a00cce888648b2262177ff2 Author: Anssi Hannula <anssi.hannula@bitwise.fi> Date: Thu Jul 2 14:49:17 2020 +0300 Fix shmat() on Linux nanomips and x86 On Linux, there are two variants of the direct shmctl syscall: - sys_shmctl: always uses shmid64_ds, does not accept IPC_64 - sys_old_shmctl: uses shmid_ds or shmid64_ds depending on IPC_64 The following Linux ABIs have the sys_old_shmctl variant: alpha, arm, microblaze, mips n32/n64, xtensa Other ABIs (and future ABIs) have the sys_shmctl variant, including ABIs that only got sys_shmctl in Linux 5.1 (such as x86, mips o32, ppc, s390x). We incorrectly assume the sys_old_shmctl variant on nanomips and x86, causing shmat() calls under valgrind to fail with EINVAL. On x86, the issue was previously masked by the non-existence of __NR_shmctl until a9fc7bceeb0b0 ("Update Linux x86 system call number definitions") in 2019. On mips o32, ppc, and s390x this issue is not visible as our headers do not have __NR_shmctl for those ABIs (396 since Linux 5.1). Fix the issue by correcting the preprocessor check in get_shm_size() to only assume the old Linux sys_old_shmctl behavior on the specific affected platforms. Also, exclude the use of direct shmctl entirely on Linux x86, ppc, mips o32, s390x in order to keep compatibility with pre-5.1 kernel versions that did not yet have direct shmctl for those ABIs. This currently only has actual effect on x86 as only it has __NR_shmctl in our headers. Fixes tests mremap4, mremap5, mremap6. https://bugs.kde.org/show_bug.cgi?id=410743 commit 7ada4d26d7cd3eb14904a398e6646f8b4e7d8a64 Author: Mark Wielaard <mark@klomp.org> Date: Wed Feb 3 16:56:14 2021 +0100 syswrap-linux.c: Pass implicit VKI_IPC_64 for shmctl also on arm64. The shmctl syscall on amd64, arm64 and riscv (but we don't have a port for that last one) always use IPC_64. Explicitly pass it to the generic PRE/POST handlers so they select the correct (64bit) data structures on those architectures. https://bugzilla.redhat.com/show_bug.cgi?id=1909548 *** Bug 423929 has been marked as a duplicate of this bug. *** |