From: Paul Floyd Date: Sat, 19 Jul 2025 16:17:35 +0000 (+0200) Subject: Bug 506910 - openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=088ac305a2f27b4d8d5822bace59742719cc84d5;p=thirdparty%2Fvalgrind.git 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. --- diff --git a/.gitignore b/.gitignore index 44454d08b..0da54a7eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1885,6 +1885,7 @@ /none/tests/linux/brk-overflow1 /none/tests/linux/brk-overflow2 /none/tests/linux/bug498317 +/none/tests/linux/bug506910 /none/tests/linux/clonev /none/tests/linux/Makefile /none/tests/linux/Makefile.in diff --git a/NEWS b/NEWS index af8810364..29e2274ea 100644 --- a/NEWS +++ b/NEWS @@ -58,6 +58,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic 506928 Wrap (deprecated) linux specific ustat syscall +506910 openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe 506930 valgrind allows SIGKILL being reset to SIG_DFL 506970 mmap needs an EBADF fd_allowed check diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 727766869..280b1ccb6 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4693,6 +4693,7 @@ PRE(sys_open) if (proc_self_exe) { // do the syscall with VG_(resolved_exename) SET_STATUS_from_SysRes(VG_(do_syscall3)(SYSNO, (Word)VG_(resolved_exename), ARG2, ARG3)); + return; } #endif // defined(VGO_linux) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index e16d293cd..d1cfdad69 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6095,6 +6095,7 @@ no_client_write: // do the syscall with VG_(resolved_exename) SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); + return; } /* Otherwise handle normally */ @@ -14093,9 +14094,9 @@ 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)); + return; } /* Otherwise handle normally */ diff --git a/none/tests/linux/Makefile.am b/none/tests/linux/Makefile.am index c81ffff54..c20b2d2d0 100644 --- a/none/tests/linux/Makefile.am +++ b/none/tests/linux/Makefile.am @@ -8,6 +8,7 @@ EXTRA_DIST = \ brk-overflow1.stderr.exp brk-overflow1.vgtest \ brk-overflow2.stderr.exp brk-overflow2.vgtest \ bug498317.stderr.exp bug498317.supp bug498317.vgtest \ + bug506910.stderr.exp bug506910.vgtest \ clonev.stdout.exp clonev.stderr.exp clonev.vgtest \ membarrier.stderr.exp membarrier.vgtest \ mremap.stderr.exp mremap.stderr.exp-glibc27 mremap.stdout.exp \ @@ -26,6 +27,7 @@ check_PROGRAMS = \ brk-overflow1 \ brk-overflow2 \ bug498317 \ + bug506910 \ clonev \ mremap \ mremap2 \ @@ -46,6 +48,7 @@ AM_CFLAGS += $(AM_FLAG_M3264_PRI) AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) # Special needs +bug506910_SOURCES = bug506910.cpp clonev_LDADD = -lpthread open_client_SOURCES = open_client.cpp pthread_stack_LDADD = -lpthread diff --git a/none/tests/linux/bug506910.cpp b/none/tests/linux/bug506910.cpp new file mode 100644 index 000000000..2dbadf56a --- /dev/null +++ b/none/tests/linux/bug506910.cpp @@ -0,0 +1,44 @@ +// For Bug 5056910 +// openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + auto pid = getpid(); + auto ppe = std::string("/proc/") + std::to_string(pid) + "/exe"; +#if defined(SYS_openat2) + struct open_how oh = { .flags=O_RDONLY, .mode=0UL, .resolve=RESOLVE_NO_MAGICLINKS }; + int res = syscall(SYS_openat2, AT_FDCWD, "/proc/self/exe", &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ELOOP) + { + throw std::runtime_error("errno should be ELOOP"); + } + } + + res = syscall(SYS_openat2, AT_FDCWD, ppe.c_str(), &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ELOOP) + { + throw std::runtime_error("errno should be ELOOP"); + } + } +#endif +} diff --git a/none/tests/linux/bug506910.stderr.exp b/none/tests/linux/bug506910.stderr.exp new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/none/tests/linux/bug506910.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/linux/bug506910.vgtest b/none/tests/linux/bug506910.vgtest new file mode 100644 index 000000000..28e3f2975 --- /dev/null +++ b/none/tests/linux/bug506910.vgtest @@ -0,0 +1 @@ +prog: bug506910