From: Paul Floyd Date: Sun, 27 Oct 2024 08:15:31 +0000 (+0100) Subject: FreeBSD sigwait syscall: fixes for unusual return codes X-Git-Tag: VALGRIND_3_24_0~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b8f138bfb904ec7489a44e44035e37711da0bb3;p=thirdparty%2Fvalgrind.git FreeBSD sigwait syscall: fixes for unusual return codes sigwait doesn't follow the usual syscall convention of returning -1 on error and setting errno. Instead it returns errno and 0 means success. Previously the POST was getting called on failure, potentially resulting in memory getting incorrectly marked as accessible and initialized. Also only flag 'may block' if the first sigset argument is accessible. --- diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 787581b86..685eb6be0 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -4010,13 +4010,16 @@ PRE(sys___acl_aclcheck_link) // int sigwait(const sigset_t * restrict set, int * restrict sig); PRE(sys_sigwait) { - *flags |= SfMayBlock; PRINT("sys_sigwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2); PRE_REG_READ2(int, "sigwait", const vki_sigset_t *, set, int *, sig); if (ARG1 != 0) { PRE_MEM_READ( "sigwait(set)", ARG1, sizeof(vki_sigset_t)); + vki_sigset_t* set = (vki_sigset_t*)ARG1; + if (ML_(safe_to_deref)(set, sizeof(vki_sigset_t))) { + *flags |= SfMayBlock; + } } if (ARG2 != 0) { PRE_MEM_WRITE( "sigwait(sig)", ARG2, sizeof(int)); @@ -4025,7 +4028,7 @@ PRE(sys_sigwait) POST(sys_sigwait) { - if (ARG2 != 0) { + if (RES == 0 && ARG2 != 0) { POST_MEM_WRITE( ARG2, sizeof(int)); } } diff --git a/memcheck/tests/freebsd/scalar.c b/memcheck/tests/freebsd/scalar.c index ef6649040..a7dd23947 100644 --- a/memcheck/tests/freebsd/scalar.c +++ b/memcheck/tests/freebsd/scalar.c @@ -1547,6 +1547,7 @@ int main(void) /* SYS_sigwait 429 */ GO(SYS_sigwait, "2s 2m"); SY(SYS_sigwait, x0+1, x0+2); SUCC; + assert(res == EFAULT); // thr_create 430 @@ -2166,6 +2167,36 @@ int main(void) GO(SYS___sysctlbyname, "(putnew) 4s 2m"); SY(SYS___sysctlbyname, x0, x0+1, NULL, NULL, x0+1, x0+2); FAIL; +#if 0 // for later + // FreeBSD 13 (and any backports) + /* SYS_shm_open2 571 */ + GO(SYS_shm_open2, " 5s 2m"); + SY(SYS_shm_open2, x0+0xf00c, x0+1, x0+2, x0+3, x0+4); FAIL; + + GO(SYS_shm_open2, " 5s 1m"); + SY(SYS_shm_open2, x0+SHM_ANON, x0+1, x0+2, x0+3, x0+4); FAIL; + + /* SYS___realpathat 574 */ + GO(SYS___realpathat, " 5s 2m"); + SY(SYS___realpathat, x0+0xffff, x0, x0, x0+100, x0+2); FAIL; + + /* SYS_close_range 575 */ + GO(SYS_close_range, "3s 0m"); + SY(SYS_close_range, x0+5, x0+10, x0); SUCC; + + /* SYS___specialfd 577 */ + GO(SYS___specialfd, "3s 1m"); + SY(SYS___specialfd, x0+0xf000, x0+1, x0+10); FAIL; + + /* SYS_aio_writev 578 */ + GO(SYS_aio_writev, "1s 1m"); + SY(SYS_aio_writev, x0+1); FAIL; + + /* SYS_aio_readv 579 */ + GO(SYS_aio_readv, "1s 1m"); + SY(SYS_aio_readv, x0+1); FAIL; +#endif + /* SYS_exit 1 */ GO(SYS_exit, "1s 0m"); SY(SYS_exit, x0); FAIL; diff --git a/memcheck/tests/freebsd/scalar.stderr.exp b/memcheck/tests/freebsd/scalar.stderr.exp index 681bb8f2a..5c61947a1 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp +++ b/memcheck/tests/freebsd/scalar.stderr.exp @@ -3605,6 +3605,10 @@ Syscall param mq_timedreceive(msg_prio) contains uninitialised byte(s) Syscall param mq_timedreceive(abs_timeout) contains uninitialised byte(s) ... +Syscall param mq_timedreceive(msg_ptr) points to unaddressable byte(s) + ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd + Syscall param mq_timedreceive(msg_prio) points to unaddressable byte(s) ... Address 0x........ is not stack'd, malloc'd or (recently) free'd @@ -3631,6 +3635,10 @@ Syscall param mq_timedsend(msg_prio) contains uninitialised byte(s) Syscall param mq_timedsend(abs_timeout) contains uninitialised byte(s) ... +Syscall param mq_timedsend(msg_ptr) points to unaddressable byte(s) + ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd + Syscall param mq_timedsend(abs_timeout) points to unaddressable byte(s) ... Address 0x........ is not stack'd, malloc'd or (recently) free'd @@ -3714,6 +3722,14 @@ Syscall param sctp_generic_sendmsg(sinfo) contains uninitialised byte(s) Syscall param sctp_generic_sendmsg(flags) contains uninitialised byte(s) ... +Syscall param sctp_generic_sendmsg(msg) points to unaddressable byte(s) + ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param sctp_generic_sendmsg(to) points to unaddressable byte(s) + ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd + Syscall param sctp_generic_sendmsg(sinfo) points to unaddressable byte(s) ... Address 0x........ is not stack'd, malloc'd or (recently) free'd