external/liborcus/UnpackedTarball_liborcus.mk |    1 
 external/liborcus/overrun.patch.0             |   63 ++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

New commits:
commit 5e7049f2ee3b4df3c249639b635e2e86d5d080eb
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Fri Jun 24 18:21:32 2022 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Fri Jun 24 22:57:52 2022 +0200

    external/liborcus: Fix heap-buffer-overflow
    
    ...as seen during CppunitTest_vcl_pdfexport:
    
    > ==573913==ERROR: AddressSanitizer: heap-buffer-overflow on address 
0x62b0001dba0e at pc 0x560576627186 bp 0x7ffeab9fa730 sp 0x7ffeab9f9ef0
    > READ of size 26624 at 0x62b0001dba0e thread T0
    >  #0 in StrtolFixAndCheck(void*, char const*, char**, char*, int) at 
~/github.com/llvm/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:3629:3
    >  #1 in strtol at 
~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:485:3
    >  #2 in 
orcus::sax_token_handler_wrapper_base::attribute(std::basic_string_view<char, 
std::char_traits<char>>, std::basic_string_view<char, std::char_traits<char>>) 
at workdir/UnpackedTarball/liborcus/src/parser/sax_token_parser.cpp:344:22
    >  #3 in 
orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper::attribute(orcus::sax::parser_attribute
 const&) at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_ns_parser.hpp:212:27
    >  #4 in 
orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper,
 orcus::sax_parser_default_config>::attribute() at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_parser.hpp:570:15
    >  #5 in 
orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper,
 orcus::sax_parser_default_config>::declaration(char const*) at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_parser.hpp:389:9
    >  #6 in 
orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper,
 orcus::sax_parser_default_config>::element() at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_parser.hpp:242:13
    >  #7 in 
orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper,
 orcus::sax_parser_default_config>::body() at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_parser.hpp:214:13
    >  #8 in 
orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper,
 orcus::sax_parser_default_config>::parse() at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_parser.hpp:182:5
    >  #9 in 
orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::parse()
 at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_ns_parser.hpp:277:14
    >  #10 in orcus::sax_token_parser<orcus::xml_stream_handler>::parse() at 
workdir/UnpackedTarball/liborcus/src/liborcus/../../include/orcus/sax_token_parser.hpp:215:14
    >  #11 in orcus::xml_stream_parser::parse() at 
workdir/UnpackedTarball/liborcus/src/liborcus/xml_stream_parser.cpp:68:9
    >  #12 in orcus::orcus_xls_xml::detect(unsigned char const*, unsigned long) 
at workdir/UnpackedTarball/liborcus/src/liborcus/orcus_xls_xml.cpp:94:16
    >  #13 in orcus::detect(unsigned char const*, unsigned long) at 
workdir/UnpackedTarball/liborcus/src/liborcus/format_detection.cpp:68:9
    >  #14 in (anonymous 
namespace)::OrcusFormatDetect::detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>&)
 at sc/source/filter/orcus/filterdetect.cxx:83:31
    > 0x62b0001dba0e is located 0 bytes to the right of 26638-byte region 
[0x62b0001d5200,0x62b0001dba0e)
    > allocated by thread T0 here:
    >  #0 in operator new[](unsigned long) at 
~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:98:3
    >  #1 in SvMemoryStream::AllocateMemory(unsigned long) at 
tools/source/stream/stream.cxx:1698:12
    >  #2 in SvMemoryStream::SvMemoryStream(unsigned long, unsigned long) at 
tools/source/stream/stream.cxx:1544:9
    >  #3 in (anonymous 
namespace)::OrcusFormatDetect::detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>&)
 at sc/source/filter/orcus/filterdetect.cxx:71:20
    
    This started to occur now after a95c585433246813096e8890b7ed6ef4fe30c621 
"Pump
    XInputStream into an SvMemoryStream rather than an OStringBuffer" no longer
    guarantees that the memory range passed into
    
      orcus::detect(const unsigned char* buffer, size_t length)
    
    is followed by a null byte at buffer[length].  (There appears to be no
    documentation for that function, but it looks unreasonable to me that it 
should
    require callers to provide a buffer thus terminated, and I rather assume 
that
    what is observed here is an orcus bug.)
    
    The problematic calls of std::strtol were used in code apparently meant to 
parse
    strings matching the XML VersionNum grammar production, and then store the 
two
    dot-separated numbers each as uint8_t.  The new code using a local readUint8
    accepts a different set of strings now than the original code using 
std::strtol,
    but the new set is arguably closer to what the actual XML VersionNum grammar
    production accepts (which is '1.' [0-9]+ for XML 1.0 and '1.1' for XML 
1.1), so
    this change should be OK.
    
    Change-Id: I1668542c96ced64667cb9f251e79126e1a54ac30
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136405
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>
    (cherry picked from commit b56f5ac2b9678d589c50e446bcbf906f4400b5fa)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136416

diff --git a/external/liborcus/UnpackedTarball_liborcus.mk 
b/external/liborcus/UnpackedTarball_liborcus.mk
index 2ad70119179b..12698bab7234 100644
--- a/external/liborcus/UnpackedTarball_liborcus.mk
+++ b/external/liborcus/UnpackedTarball_liborcus.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,liborcus,\
        external/liborcus/forcepoint-88.patch.1 \
        external/liborcus/forcepoint-95.patch.1 \
        external/liborcus/include.patch.0 \
+       external/liborcus/overrun.patch.0 \
 ))
 
 ifeq ($(OS),WNT)
diff --git a/external/liborcus/overrun.patch.0 
b/external/liborcus/overrun.patch.0
new file mode 100644
index 000000000000..de2097e32328
--- /dev/null
+++ b/external/liborcus/overrun.patch.0
@@ -0,0 +1,63 @@
+--- src/parser/sax_token_parser.cpp
++++ src/parser/sax_token_parser.cpp
+@@ -10,6 +10,7 @@
+ 
+ #include <mdds/sorted_string_map.hpp>
+ #include <cctype>
++#include <limits>
+ 
+ namespace orcus {
+ 
+@@ -329,6 +330,28 @@
+     m_elem.raw_name = elem.name;
+ }
+ 
++static uint8_t readUint8(char const * begin, char const * end, char const ** 
endptr) {
++    unsigned n = 0;
++    char const * p = begin;
++    for (; p != end; ++p) {
++        char const c = *p;
++        if (c < '0' || c > '9') {
++            break;
++        }
++        n = 10 * n + (c - '0');
++        if (n > std::numeric_limits<uint8_t>::max()) {
++            *endptr = nullptr;
++            return 0;
++        }
++    }
++    if (p == begin) {
++        *endptr = nullptr;
++        return 0;
++    }
++    *endptr = p;
++    return n;
++}
++
+ void sax_token_handler_wrapper_base::attribute(std::string_view name, 
std::string_view val)
+ {
+     decl_attr_type dat = decl_attr::get().find(name.data(), name.size());
+@@ -340,18 +362,18 @@
+             const char* p = val.data();
+             const char* p_end = p + val.size();
+ 
+-            char* endptr = nullptr;
+-            long v = std::strtol(p, &endptr, 10);
++            const char* endptr = nullptr;
++            uint8_t v = readUint8(p, p_end, &endptr);
+ 
+-            if (!endptr || endptr >= p_end || *endptr != '.')
++            if (!endptr || endptr == p_end || *endptr != '.')
+                 break;
+ 
+             m_declaration.version_major = v;
+             p = endptr + 1;
+ 
+-            v = std::strtol(p, &endptr, 10);
++            v = readUint8(p, p_end, &endptr);
+ 
+-            if (!endptr || endptr > p_end)
++            if (!endptr)
+                 break;
+ 
+             m_declaration.version_minor = v;

Reply via email to