diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-06-24 18:21:32 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-06-24 21:36:34 +0200 |
commit | 3f17a643d0f943d02c7cb2b5d8e702fe0e63e38d (patch) | |
tree | f050b8933dfd6511420b6af5974c9143a9bb7ee0 /external | |
parent | 79f3abc0e200ffa772bc7722b5f384eb538d7576 (diff) |
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 <sbergman@redhat.com>
Diffstat (limited to 'external')
-rw-r--r-- | external/liborcus/UnpackedTarball_liborcus.mk | 1 | ||||
-rw-r--r-- | external/liborcus/overrun.patch.0 | 63 |
2 files changed, 64 insertions, 0 deletions
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; |