]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 428364 - Signals inside io_uring_enter not handled
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 18 Nov 2023 12:02:30 +0000 (13:02 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 18 Nov 2023 12:02:30 +0000 (13:02 +0100)
Patch provide by
    Andrew Soutar kdebugtraq@andrewsoutar.com
Thanks!

I haven't added the reproducers as they require interrupting
the Valgrind process. Maybe the tests can be adapted to use
fork and have the parent kill the child running io_uring.

NEWS
coregrind/m_syswrap/syswrap-linux.c

diff --git a/NEWS b/NEWS
index 98d8ab5466be0474673cc982556af56e4bb374ef..1bfdd52615becd5814844bb9cd0392b3df1df9b6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 
 
 401284  False positive "Source and destination overlap in strncat"
+428364  Signals inside io_uring_enter not handled
 437790  valgrind reports "Conditional jump or move depends on uninitialised
         value" in memchr of macOS 10.12-10.15
 460616  disInstr(arm64): unhandled instruction 0x4E819402 (dotprod/ASIMDDP)
index 18286c488446b846b31a57a4e4a43389dd695322..0cc6221976e8d0db2f2e484e38939003c1597168 100644 (file)
@@ -1959,6 +1959,33 @@ POST(sys_pselect6_time64)
    }
 }
 
+static void blocking_syscall_sigmask_pre ( ThreadId tid,
+                                           Addr *sig_p, vki_size_t sigsz,
+                                           const HChar *sig_mem_name,
+                                           const HChar *malloc_str )
+{
+   if (*sig_p != 0 && sigsz == sizeof(vki_sigset_t)) {
+      const vki_sigset_t *guest_sigmask = (vki_sigset_t *) *sig_p;
+      PRE_MEM_READ(sig_mem_name, *sig_p, sigsz);
+      if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
+         *sig_p = 1; /* Something recognizable to PST() hook. */
+      } else {
+         vki_sigset_t *vg_sigmask =
+            VG_(malloc)(malloc_str, sizeof(*vg_sigmask));
+         *sig_p = (Addr)vg_sigmask;
+         *vg_sigmask = *guest_sigmask;
+         VG_(sanitize_client_sigmask)(vg_sigmask);
+      }
+   }
+}
+
+static void blocking_syscall_sigmask_post ( Addr sig, vki_size_t sigsz )
+{
+   if (sig != 0 && sigsz == sizeof(vki_sigset_t) && sig != 1) {
+      VG_(free)((vki_sigset_t *)sig);
+   }
+}
+
 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
                                SyscallArgs* arrghs, SyscallStatus* status,
                                UWord* flags, Bool is_time64 )
@@ -2000,19 +2027,9 @@ static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
                        sizeof(struct vki_timespec) );
       }
    }
-   if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
-      const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
-      PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
-      if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
-         ARG4 = 1; /* Something recognisable to POST() hook. */
-      } else {
-         vki_sigset_t *vg_sigmask =
-             VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
-         ARG4 = (Addr)vg_sigmask;
-         *vg_sigmask = *guest_sigmask;
-         VG_(sanitize_client_sigmask)(vg_sigmask);
-      }
-   }
+   blocking_syscall_sigmask_pre(tid, (Addr *)&ARG4, ARG5,
+                                "ppoll(sigmask)",
+                                "syswrap.ppoll.1");
 }
 
 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
@@ -2025,9 +2042,7 @@ static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
       for (i = 0; i < ARG2; i++)
         POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
    }
-   if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
-      VG_(free)((vki_sigset_t *) (Addr)ARG4);
-   }
+   blocking_syscall_sigmask_post((Addr)ARG4, ARG5);
 }
 
 PRE(sys_ppoll)
@@ -2149,7 +2164,7 @@ POST(sys_epoll_wait)
 
 PRE(sys_epoll_pwait)
 {
-   *flags |= SfMayBlock;
+   *flags |= SfMayBlock | SfPostOnFail;
    PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
           FMT_REGWORD "x, %" FMT_REGWORD "u )",
          SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
@@ -2159,12 +2174,15 @@ PRE(sys_epoll_pwait)
                  vki_size_t, sigsetsize);
    /* Assume all (maxevents) events records should be (fully) writable. */
    PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
-   if (ARG5)
-      PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
+   blocking_syscall_sigmask_pre(tid, (Addr *)&ARG5, ARG6,
+                                "epoll_pwait(sigmask)",
+                                "syswrap.epoll_pwait.1");
 }
 POST(sys_epoll_pwait)
 {
-   epoll_post_helper (tid, arrghs, status);
+   if (SUCCESS)
+      epoll_post_helper (tid, arrghs, status);
+   blocking_syscall_sigmask_post((Addr) ARG5, ARG6);
 }
 
 PRE(sys_epoll_pwait2)
@@ -13326,6 +13344,7 @@ POST(sys_io_uring_setup)
 
 PRE(sys_io_uring_enter)
 {
+   *flags |= SfMayBlock | SfPostOnFail;
    PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
          FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
          FMT_REGWORD "u )",
@@ -13334,12 +13353,14 @@ PRE(sys_io_uring_enter)
                  unsigned int, fd, unsigned int, to_submit,
                  unsigned int, min_complete, unsigned int, flags,
                  const void *, sig, unsigned long, sigsz);
-   if (ARG5)
-      PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
+   blocking_syscall_sigmask_pre(tid, (Addr *)&ARG5, ARG6,
+                                "io_uring_enter(sig)",
+                                "syswrap.io_uring_enter.1");
 }
 
 POST(sys_io_uring_enter)
 {
+   blocking_syscall_sigmask_post((Addr)ARG5, ARG6);
 }
 
 PRE(sys_io_uring_register)