|
From: <sv...@va...> - 2016-10-01 11:54:52
|
Author: mjw
Date: Sat Oct 1 12:54:41 2016
New Revision: 15991
Log:
Fix crash in msghdr_foreachfield when iov_len isn't safe to dereference.
Also stop checking when max length of bytes have been reached.
Bug #369359
Found by LTP testcases/kernel/syscalls/recvmsg/recvmsg01.
Modified:
trunk/NEWS
trunk/coregrind/m_syswrap/syswrap-generic.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sat Oct 1 12:54:41 2016
@@ -181,6 +181,7 @@
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
Modified: trunk/coregrind/m_syswrap/syswrap-generic.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-generic.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-generic.c Sat Oct 1 12:54:41 2016
@@ -1056,15 +1056,19 @@
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;
+ }
+ }
}
}
|