valgrind/valgrind-3.16.1-open-proc-self-exe.patch
DistroBaker 46ceca4835 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/valgrind.git#694bfef4aa9f24859dcf6c1c4a6b68c9a242ddf0
2021-02-07 02:44:47 +00:00

99 lines
3.4 KiB
Diff

diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h
index 4717abac6..c50b31399 100644
--- a/coregrind/m_syswrap/priv_syswrap-generic.h
+++ b/coregrind/m_syswrap/priv_syswrap-generic.h
@@ -106,6 +106,10 @@ extern Bool
ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
int flags);
+extern Bool
+ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename,
+ int flags);
+
/* Helper function for generic mprotect and linux pkey_mprotect. */
extern void handle_sys_mprotect (ThreadId tid, SyscallStatus *status,
Addr *addr, SizeT *len, Int *prot);
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 7d4b385a3..3810f7474 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -4078,6 +4078,38 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
}
#endif // defined(VGO_linux) || defined(VGO_solaris)
+#if defined(VGO_linux)
+Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename,
+ int flags)
+{
+ HChar name[30]; // large enough for /proc/<int>/exe
+
+ if (!ML_(safe_to_deref)((const void *) filename, 1))
+ return False;
+
+ /* Opening /proc/<pid>/exe or /proc/self/exe? */
+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
+ if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe"))
+ return False;
+
+ /* Allow to open the file only for reading. */
+ if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
+ SET_STATUS_Failure(VKI_EACCES);
+ return True;
+ }
+
+ SysRes sres = VG_(dup)(VG_(cl_exec_fd));
+ SET_STATUS_from_SysRes(sres);
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
+ if (off < 0)
+ SET_STATUS_Failure(VKI_EMFILE);
+ }
+
+ return True;
+}
+#endif // defined(VGO_linux)
+
PRE(sys_open)
{
if (ARG2 & VKI_O_CREAT) {
@@ -4119,8 +4151,10 @@ PRE(sys_open)
}
}
- /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv. */
- if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2))
+ /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv
+ or /proc/self/exe or /proc/<pid>/exe. */
+ if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)
+ || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2))
return;
#endif // defined(VGO_linux)
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 52074149d..fcc534454 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -5745,6 +5745,22 @@ PRE(sys_openat)
return;
}
+ /* And for /proc/self/exe or /proc/<pid>/exe case. */
+
+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
+ && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
+ || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
+ sres = VG_(dup)( VG_(cl_exec_fd) );
+ SET_STATUS_from_SysRes( sres );
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
+ if (off < 0)
+ SET_STATUS_Failure( VKI_EMFILE );
+ }
+ return;
+ }
+
/* Otherwise handle normally */
*flags |= SfMayBlock;
}