Bug 506910 - openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe
Summary: openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Paul Floyd
URL:
Keywords:
Depends on:
Blocks: 506971
  Show dependency treegraph
 
Reported: 2025-07-11 12:29 UTC by Mark Wielaard
Modified: 2025-07-19 21:15 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2025-07-11 12:29:06 UTC
The LTP testcase openat202 fails because an openat call succeeds opening /proc/self/exe even when RESOLVE_NO_MAGICLINKS is given. Probably because /proc/self/exe is a special file under valgrind.

openat202.c:62: TFAIL: resolve-no-magiclinks: openat2() passed unexpectedly
Comment 1 Mark Wielaard 2025-07-19 15:26:03 UTC
After

commit 7fb17b67f40eb8197c45b5f575daf4fa77d16faa (HEAD -> master, origin/master, origin/HEAD)
Author: Paul Floyd <pjfloyd@wanadoo.fr>
Date:   Sat Jul 19 15:10:31 2025 +0200

    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

The LTP openat202 testcase still fails for me (Fedora 42, x86_64)

$ make ltpchecks TESTS=openat202
[1/1] Testing openat202 ...
openat202: unempty log2.filtered:

valgrind: m_syswrap/syswrap-main.c:2441 (vgPlain_client_syscall): Assertion '0 == (sci->flags & ~(SfPollAfter | SfYieldAfter | SfNoWriteResult))' failed.

host stacktrace:
==1151383==    at 0x58028188: show_sched_status_wrk (m_libcassert.c:426)
==1151383==    by 0x580282A7: report_and_quit (m_libcassert.c:497)
==1151383==    by 0x58028435: vgPlain_assert_fail (m_libcassert.c:564)
==1151383==    by 0x58014BBA: vgPlain_client_syscall (syswrap-main.c:2441)
==1151383==    by 0x58010A5A: handle_syscall (scheduler.c:1214)
==1151383==    by 0x580128C6: vgPlain_scheduler (scheduler.c:1588)
==1151383==    by 0x5807EBFA: run_a_thread_NORETURN (syswrap-linux.c:102)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable syscall 437 (lwpid 1151383)
==1151383==    at 0x4946A8D: syscall (syscall.S:38)
==1151383==    by 0x4013A7: run (openat2.h:53)
==1151383==    by 0x40AD54: fork_testrun.isra.0 (tst_test.c:1617)
==1151383==    by 0x40D113: tst_run_tcases (tst_test.c:1970)
==1151383==    by 0x4011BD: main (tst_test.h:729)
client stack range: [0x1FFEFFC000 0x1FFF000FFF] client SP: 0x1FFEFFF228
valgrind stack range: [0x100278E000 0x100288DFFF] top usage: 17832 of 1048576


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.
Comment 2 Mark Wielaard 2025-07-19 19:50:05 UTC
The issue seems to be that at the end of sys_openat2 if we detected it was called on proc_self_exe then we want to force the syscall with VG_(resolved_exename) as ARG2 and SET_STATUS_from_SysRes. But then fall through to where we set flags to contain SfMayBlock. 

We could do an immediate return after:
      // do the syscall with VG_(resolved_exename)                              
      SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4));
      return;

But since it is the same syscall it seems simpler to just modify ARG2 and fall through.

Testing the following patch:

diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index e16d293cd08f..1499e75bccf0 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -6094,7 +6094,7 @@ no_client_write:
    if (proc_self_exe) {
 
       // do the syscall with VG_(resolved_exename)
-      SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4));
+      ARG2 = (Word)VG_(resolved_exename);
    }
 
    /* Otherwise handle normally */
@@ -14095,7 +14095,8 @@ PRE(sys_openat2)
    if (proc_self_exe) {
 
       // do the syscall with VG_(resolved_exename)
-      SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4));
+      ARG2 = (Word)VG_(resolved_exename);
+
    }
 
    /* Otherwise handle normally */
Comment 3 Mark Wielaard 2025-07-19 21:15:39 UTC
commit 088ac305a2f27b4d8d5822bace59742719cc84d5
Author: Paul Floyd <pjfloyd@wanadoo.fr>
Date:   Sat Jul 19 18:17:35 2025 +0200

    Bug 506910 - openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe
    
    Previous change did most of the work but need to return without setting
    SfMayBlock. Add a testcase covering /proc/self/exe and /proc/PID/exe.