From c49efc1cff161a8cfa741900c262f5b1c03f82b3 Mon Sep 17 00:00:00 2001 From: Paul Floyd Date: Sat, 18 Nov 2023 13:02:30 +0100 Subject: [PATCH] Bug 428364 - Signals inside io_uring_enter not handled 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 | 1 + coregrind/m_syswrap/syswrap-linux.c | 65 +++++++++++++++++++---------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 98d8ab5466..1bfdd52615 100644 --- 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) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 18286c4884..0cc6221976 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -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) -- 2.47.2