]> git.ipfire.org Git - thirdparty/valgrind.git/commit
Bug 505673 - Valgrind crashes with an internal error and SIGBUS when the guest tries...
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 19 Jul 2025 13:10:31 +0000 (15:10 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 19 Jul 2025 13:10:31 +0000 (15:10 +0200)
commit7fb17b67f40eb8197c45b5f575daf4fa77d16faa
tree8166f25ec136b56ac7158d299d422f1b063c9d0b
parentbaac076edfde2870ee6cc69390f3bca9d4f7d974
Bug 505673 - Valgrind crashes with an internal error and SIGBUS when the guest tries to open its own file with O_WRONLY|O_CREAT|O_TRUNC

This is all quite messy.

It affects open() openat() and openat2() (the last of which is Linux only).
On Linux we also need to check for /proc/self/exe and /proc/PID/exe.
On Linux there are also a couple of RESOLVE flags for openat2() that
mean _don't_ check /proc magic links.
In the general case we need to have some reference to check whether
the filename matches the guest filename. So I've added that as
VG_(resolved_exename) (which I was already using on FreeBSD).
The pathname also needs to be canonicalised. It may be a
relative path, symlink or use RESOLVE_IN_ROOT. That uses
VG_(realpath) (again which was already present for FreBSD).
On illumos the man page says that opening running binaries for
writing failes with errno set to ETXTBSY but that's not what
the open functions do - they just open the file. So I've done nothing
for illumos or Solaris. Maybe I'll open an illumos ticket.
I haven't tried on Darwin.

The Linux open functions with /proc/self/exe and /proc/PID/exe
were just calling dup on the fd that we hold for the client exe.
That means that we were ignoring any other flags. That has now changed.
If the open doesn't fail because the WRONLY/RDWR flags are set then
the syscall gets called from the PRE wrapper using VG_(resolved_exename)
instewad of the /proc pathname.

I haven't tried to handle all of the Linux openat2 RESOLVE*
flags. RESOLVE_NO_MAGICLINKS is handled and I see the LTS test
openat202 now passing, so this should also fix Bug 506910.

I'm not sure that VG_(realpath) handles all forms of weird path
resolution on Linux (on FreeBSD it uses a syscall so that should
work OK).
19 files changed:
.gitignore
NEWS
coregrind/m_initimg/initimg-freebsd.c
coregrind/m_initimg/initimg-linux.c
coregrind/m_libcfile.c
coregrind/m_syswrap/syswrap-freebsd.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/pub_core_libcfile.h
include/pub_tool_libcfile.h
memcheck/tests/x86-linux/scalar_openat2.stderr.exp
none/tests/freebsd/Makefile.am
none/tests/freebsd/open_client.cpp [new file with mode: 0644]
none/tests/freebsd/open_client.stderr.exp [new file with mode: 0644]
none/tests/freebsd/open_client.vgtest [new file with mode: 0644]
none/tests/linux/Makefile.am
none/tests/linux/open_client.cpp [new file with mode: 0644]
none/tests/linux/open_client.stderr.exp [new file with mode: 0644]
none/tests/linux/open_client.vgtest [new file with mode: 0644]