]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 424012 - fix crash if readv/writev have invalid but not NULL arg2 iovec pointer
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 9 Nov 2020 08:30:31 +0000 (09:30 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 9 Nov 2020 08:30:31 +0000 (09:30 +0100)
coregrind/m_syswrap/syswrap-generic.c
memcheck/tests/writev1.c
memcheck/tests/writev1.stderr.exp

index 864bda76c576b3513dc663df263495c93dc3da31..badb8c778dd2771a2cb9c1670785ac4071a8d95f 100644 (file)
@@ -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[...])",
index 6a8c281c898cbe6968bac4eacdf61c79a2b83a03..f537058e919a71546e4c39e0328aedc5b0c7d411 100644 (file)
@@ -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;
index 0fe62eecb7b835f13d8f24b60c8eacefe4365680..aea8390c74a3663c4f921b3985d44c3041b3281f 100644 (file)
@@ -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