From: Paul Floyd Date: Mon, 9 Nov 2020 08:30:31 +0000 (+0100) Subject: Bug 424012 - fix crash if readv/writev have invalid but not NULL arg2 iovec pointer X-Git-Tag: VALGRIND_3_17_0~130 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3aa3482774cf99ba23b7a6eac97d17cf143af5aa;p=thirdparty%2Fvalgrind.git Bug 424012 - fix crash if readv/writev have invalid but not NULL arg2 iovec pointer --- diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 864bda76c5..badb8c778d 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4291,8 +4291,7 @@ PRE(sys_readv) if ((Int)ARG3 >= 0) PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) ); - if (ARG2 != 0) { - /* ToDo: don't do any of the following if the vector is invalid */ + if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) { vec = (struct vki_iovec *)(Addr)ARG2; for (i = 0; i < (Int)ARG3; i++) PRE_MEM_WRITE( "readv(vector[...])", @@ -4644,8 +4643,8 @@ PRE(sys_writev) if ((Int)ARG3 >= 0) PRE_MEM_READ( "writev(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) ); - if (ARG2 != 0) { - /* ToDo: don't do any of the following if the vector is invalid */ + + if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) { vec = (struct vki_iovec *)(Addr)ARG2; for (i = 0; i < (Int)ARG3; i++) PRE_MEM_READ( "writev(vector[...])", diff --git a/memcheck/tests/writev1.c b/memcheck/tests/writev1.c index 6a8c281c89..f537058e91 100644 --- a/memcheck/tests/writev1.c +++ b/memcheck/tests/writev1.c @@ -82,6 +82,26 @@ int main(void) else fprintf(stderr, "Error readv returned a positive value\n"); + // test with totally bogus iovec pointer + // see bugz 424012 + if (writev(fd, (const struct iovec *)1, 1) < 0) { + if (errno == EFAULT) + fprintf(stderr, "Received EFAULT as expected\n"); + else + fprintf(stderr, "Expected EFAULT, got %d\n", errno); + } + else + fprintf(stderr, "Error writev returned a positive value\n"); + + if (readv(fd, (const struct iovec *)1, 1) < 0) { + if (errno == EFAULT) + fprintf(stderr, "Received EFAULT as expected\n"); + else + fprintf(stderr, "Expected EFAULT, got %d\n", errno); + } + else + fprintf(stderr, "Error readv returned a positive value\n"); + unlink(f_name); return 0; diff --git a/memcheck/tests/writev1.stderr.exp b/memcheck/tests/writev1.stderr.exp index 0fe62eecb7..aea8390c74 100644 --- a/memcheck/tests/writev1.stderr.exp +++ b/memcheck/tests/writev1.stderr.exp @@ -7,3 +7,15 @@ Syscall param writev(vector[...]) points to unaddressable byte(s) Received EFAULT as expected Received EINVAL as expected Received EINVAL as expected +Syscall param writev(vector) points to unaddressable byte(s) + ... + by 0x........: main (writev1.c:87) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Received EFAULT as expected +Syscall param readv(vector) points to unaddressable byte(s) + ... + by 0x........: main (writev1.c:96) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Received EFAULT as expected