From: Paul Floyd Date: Fri, 2 May 2025 16:53:09 +0000 (+0200) Subject: Bug 503641 - close_range syscalls started failing with 3.25.0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=933e542b431f17681cc915de656e853dc16d4fe7;p=thirdparty%2Fvalgrind.git Bug 503641 - close_range syscalls started failing with 3.25.0 --- diff --git a/NEWS b/NEWS index 6a15080c1..71c389c53 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. +503641 close_range syscalls started failing with 3.25.0 To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index de710c97e..6f3917830 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -13699,17 +13699,20 @@ PRE(sys_execveat) PRE(sys_close_range) { - SysRes res = VG_(mk_SysRes_Success)(0); - Int beg, end; - Int first = ARG1; - Int last = ARG2; + UInt first = ARG1; + UInt last = ARG2; + + vg_assert(VG_(log_output_sink).fd == -1 || + VG_(log_output_sink).fd >= VG_(fd_hard_limit)); + vg_assert(VG_(xml_output_sink).fd == -1 || + VG_(xml_output_sink).fd >= VG_(fd_hard_limit)); FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3); PRE_REG_READ3(long, "close_range", unsigned int, first, unsigned int, last, - unsigned int, flags); + int, flags); if (first > last) { SET_STATUS_Failure( VKI_EINVAL ); @@ -13724,29 +13727,28 @@ PRE(sys_close_range) return; } - beg = end = first; - do { - if (end > last - || (end == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0) - || end == VG_(log_output_sink).fd - || end == VG_(xml_output_sink).fd) { - /* Split the range if it contains a file descriptor we're not - * supposed to close. */ - if (end - 1 >= beg) - res = VG_(do_syscall3)(__NR_close_range, (UWord)beg, (UWord)end - 1, ARG3 ); - beg = end + 1; + if (VG_(debugLog_getLevel)() > 0 && + first <= 2U && + last >= 2U && + first != last) { + SysRes res = VG_(mk_SysRes_Success)(0); + if (first <= 1U) { + res = VG_(do_syscall3)(__NR_close_range, first, 1U, ARG3); } - } while (end++ <= last); - - /* If it failed along the way, it's presumably the flags being wrong. */ - SET_STATUS_from_SysRes (res); + if (!sr_isError(res) && last >= 3U) { + res = VG_(do_syscall3)(__NR_close_range, 3U, last, ARG3); + } + /* If it failed along the way, it's presumably the flags being wrong. */ + SET_STATUS_from_SysRes (res); + } else { + SET_STATUS_from_SysRes(VG_(do_syscall3)(__NR_close_range, first, last, ARG3)); + } } POST(sys_close_range) { - Int fd; - Int first = ARG1; - Int last = ARG2; + UInt fd; + UInt last = ARG2; if (!VG_(clo_track_fds) || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0) @@ -13757,13 +13759,11 @@ POST(sys_close_range) /* If the close_range range is too wide, we don't want to loop through the whole range. */ - if (last == ~0U) - ML_(record_fd_close_range)(tid, first); + if (ARG2 >= VG_(fd_hard_limit)) + ML_(record_fd_close_range)(tid, ARG1); else { - for (fd = first; fd <= last; fd++) - if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0) - && fd != VG_(log_output_sink).fd - && fd != VG_(xml_output_sink).fd) + for (fd = ARG1; fd <= last; fd++) + if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)) ML_(record_fd_close)(tid, fd); } } diff --git a/memcheck/tests/close_range.stderr.exp.linux b/memcheck/tests/close_range.stderr.exp.linux index 3a0de7837..93c4bfa27 100644 --- a/memcheck/tests/close_range.stderr.exp.linux +++ b/memcheck/tests/close_range.stderr.exp.linux @@ -1,12 +1,12 @@ Syscall param close_range(first) contains uninitialised byte(s) at 0x........: close_range (in /...libc...) - by 0x........: main (close_range.c:89) + by 0x........: main (close_range.c:92) Syscall param close_range(last) contains uninitialised byte(s) at 0x........: close_range (in /...libc...) - by 0x........: main (close_range.c:89) + by 0x........: main (close_range.c:92) Syscall param close_range(flags) contains uninitialised byte(s) at 0x........: close_range (in /...libc...) - by 0x........: main (close_range.c:89) + by 0x........: main (close_range.c:92)