]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix crash in msghdr_foreachfield when iov_len isn't safe to dereference.
authorMark Wielaard <mark@klomp.org>
Sat, 1 Oct 2016 11:54:41 +0000 (11:54 +0000)
committerMark Wielaard <mark@klomp.org>
Sat, 1 Oct 2016 11:54:41 +0000 (11:54 +0000)
Also stop checking when max length of bytes have been reached.

Bug #369359
Found by LTP testcases/kernel/syscalls/recvmsg/recvmsg01.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15991

NEWS
coregrind/m_syswrap/syswrap-generic.c

diff --git a/NEWS b/NEWS
index ae55de72f6cbb14bcf8531e19b54c314a7a47a84..d8c1c869e3ea3d32278902acb05e7b750fe7c08c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -181,6 +181,7 @@ where XXXXXX is the bug number as listed below.
 369169  ppc64 fails jm_int_isa_2_07 test
 369209  valgrind loops and eats up all memory if cwd doesn't exist.
 369356  pre_mem_read_sockaddr syscall wrapper can crash with bad sockaddr
+369359  msghdr_foreachfield can crash when handling bad iovec
 
 n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 and amd64
 n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap
index be887b1653b86abf8f484fbe16c2ac26636cf70a..957a6152ce17ca6b12f1e4dcfd10eb5d02e747a5 100644 (file)
@@ -1056,15 +1056,19 @@ void msghdr_foreachfield (
 
       VG_(sprintf) ( fieldName, "(%s.msg_iov)", name );
 
-      foreach_func ( tid, True, fieldName, 
-                     (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
-
-      for ( i = 0; i < msg->msg_iovlen; ++i, ++iov ) {
-         UInt iov_len = iov->iov_len <= length ? iov->iov_len : length;
-         VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i );
-         foreach_func ( tid, False, fieldName, 
-                        (Addr)iov->iov_base, iov_len );
-         length = length - iov_len;
+      if (ML_(safe_to_deref)(&msg->msg_iovlen, sizeof (UInt))) {
+         foreach_func ( tid, True, fieldName, (Addr)iov,
+                        msg->msg_iovlen * sizeof( struct vki_iovec ) );
+
+         for ( i = 0; i < msg->msg_iovlen && length > 0; ++i, ++iov ) {
+            if (ML_(safe_to_deref)(&iov->iov_len, sizeof (UInt))) {
+               UInt iov_len = iov->iov_len <= length ? iov->iov_len : length;
+               VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i );
+               foreach_func ( tid, False, fieldName,
+                              (Addr)iov->iov_base, iov_len );
+               length = length - iov_len;
+            }
+         }
       }
    }