From 1a3cb25a7cd88857a959f2eb3ad68e0b21e90034 Mon Sep 17 00:00:00 2001
From: alvaro <alvaro.felipe91@gmail.com>
Date: Tue, 4 Jul 2017 22:04:37 +0200
Subject: [PATCH] Fix oob read terminating data with 0

Fix crash e3c41070342cf84dea077356ddbb8ebf4326a601

==12073==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6110000003bb at pc 0x0000004c234c bp 0x7fcf6359ec30 sp 0x7fcf6359e3
e0
READ of size 11 at 0x6110000003bb thread T0
    #0 0x4c234b in __interceptor_strlen.part.30 /home/alvaro/tools/llvm/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitize
r_common_interceptors.inc:301
    #1 0x7165e6579d87 in std::char_traits<char>::length(char const*) /build/gcc-multilib/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3
/include/bits/char_traits.h:269
    #2 0x7165e6579d87 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std
::allocator<char> const&) /build/gcc-multilib/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:495
    #3 0x5c3333 in ELFIO::elfio::load_sections(std::istream&) /home/alvaro/fuzzers/elfio/ELFIO/examples/libfuzzer/../../elfio/elfio.hpp
:413:44
---
 elfio/elfio_section.hpp | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/elfio/elfio_section.hpp b/elfio/elfio_section.hpp
index a226ba4..9d6c654 100644
--- a/elfio/elfio_section.hpp
+++ b/elfio/elfio_section.hpp
@@ -243,19 +243,20 @@ class section_impl : public section
 
 
         Elf_Xword size = get_size();
-        if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size()) {
-            try {
-                data = new char[size];
-            } catch (const std::bad_alloc&) {
-                data      = 0;
-                data_size = 0;
-            }
-            if ( 0 != size ) {
-                stream.seekg( (*convertor)( header.sh_offset ) );
-                stream.read( data, size );
-                data_size = size;
-            }
-        }
+	if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size()) {
+	    try {
+		data = new char[size + 1];
+	    } catch (const std::bad_alloc&) {
+		data      = 0;
+		data_size = 0;
+	    }
+	    if ( 0 != size ) {
+		stream.seekg( (*convertor)( header.sh_offset ) );
+		stream.read( data, size );
+		data[size] = 0; //ensure data is ended with 0 to avoid oob read
+		data_size = size;
+	    }
+	}
     }
 
 //------------------------------------------------------------------------------
-- 
GitLab