Submit #764646: xlnt-community xlnt commit bceb706 and before Memory Corruptioninfo

Titelxlnt-community xlnt commit bceb706 and before Memory Corruption
Beschreibung### Description We discovered a Segmentation Fault vulnerability in xlnt. The crash occurs in xlnt::detail::compound_document::read_directory when parsing the directory structure of an encrypted XLSX (OLE Compound Document) file. The ASAN report indicates a SEGV on an unknown address (0x51d04d8016c2). This address is neither NULL nor adjacent to a valid heap region, suggesting a Wild Pointer dereference or a Far-Out-Of-Bounds Read. This likely happens when the parser reads a corrupted or malicious index/offset from the directory stream and uses it to access memory without bounds checking. Vendor confirmed and create a pull request [#147](https://github.com/xlnt-community/xlnt/pull/147). ### Environment - OS: Linux x86_64 - Complier: Clang - Build Configuration: Release mode with ASan enabled. ### Vulnerability Details - Target: xlnt - Vulnerability Type: CWE-125: Out-of-bounds Read / CWE-129: Improper Validation of Array Index - Function: xlnt::detail::compound_document::read_directory - Location: source/detail/cryptography/compound_document.cpp:976:34 - Caller: compound_document::compound_document (Constructor) - Root Cause Analysis: The read_directory function iterates through the directory entries of the OLE container. The OLE format uses indices (integers) to link directory entries (e.g., Left Child, Right Child, Root Node). The crash at line 976 likely involves accessing a directory entry or a sector using an index read directly from the file. If this index is maliciously crafted (e.g., a very large number), it causes the program to access an unmapped memory region (0x51d04d8016c2), resulting in an immediate crash. ### Reproduce 1. Build xlnt and harness with Release optimization and ASAN enabled. <details> <summary>harness.c</summary> ``` #include <xlnt/xlnt.hpp> #include <iostream> #include <string> #include <vector> int main(int argc, char **argv) { if (argc < 2) { return 0; } std::string filepath = argv[1]; try { xlnt::workbook wb; wb.load(filepath); if (wb.sheet_count() > 0) { auto ws = wb.active_sheet(); for (auto row : ws.rows(false)) { for (auto cell : row) { (void)cell.to_string(); } } } } catch (const xlnt::exception& e) { } catch (const std::exception& e) { } catch (...) { } return 0; } ``` </details> 2. Run with the crashing [file](https://github.com/oneafter/0128/blob/main/xl5/repro): ``` ./harness repro ``` <details> <summary>ASAN report</summary> ``` AddressSanitizer:DEADLYSIGNAL ================================================================= ==46164==ERROR: AddressSanitizer: SEGV on unknown address 0x51d04d8016c2 (pc 0x7f7142b09c8d bp 0x7ffda74eb9f0 sp 0x7ffda74eb7e0 T0) ==46164==The signal is caused by a READ memory access. #0 0x7f7142b09c8d in xlnt::detail::compound_document::read_directory() /src/repro/xlnt/source/detail/cryptography/compound_document.cpp:976:34 #1 0x7f7142b06cb2 in xlnt::detail::compound_document::compound_document(std::istream&) /src/repro/xlnt/source/detail/cryptography/compound_document.cpp:518:5 #2 0x7f7142b69660 in (anonymous namespace)::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char>> const&, std::__cxx11::basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t>> const&) /src/repro/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:321:37 #3 0x7f7142b69660 in xlnt::detail::decrypt_xlsx(std::vector<unsigned char, std::allocator<unsigned char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /src/repro/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:340:12 #4 0x7f7142b6d63e in void xlnt::detail::xlsx_consumer::read_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /src/repro/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:354:28 #5 0x7f714292441a in xlnt::workbook::load(std::istream&) /src/repro/xlnt/source/workbook/workbook.cpp:972:22 #6 0x7f7142922415 in xlnt::workbook::load(xlnt::path const&) /src/repro/xlnt/source/workbook/workbook.cpp:1020:5 #7 0x7f714295b2c2 in void xlnt::workbook::load_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /src/repro/xlnt/source/workbook/workbook.cpp:996:12 #8 0x7f714295b2c2 in xlnt::workbook::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /src/repro/xlnt/source/workbook/workbook.cpp:1007:12 #9 0x5568fc21e2be in main /src/repro/xlnt/fuzz_xlnt.cpp:18:12 #10 0x7f71420dd1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #11 0x7f71420dd28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #12 0x5568fc13a584 in _start (/src/repro/xlnt/fuzz_xlnt+0x2d584) (BuildId: 0ed0b9c74d771dd96d8c9fdc9cc1d67cc1986854) ==46164==Register values: rax = 0x0000000000000000 rbx = 0x00007ffda74eb7e0 rcx = 0x0000000000000000 rdx = 0x0000000000013a73 rdi = 0x000051d04d8016c2 rsi = 0x0000502000000750 rbp = 0x00007ffda74eb9f0 rsp = 0x00007ffda74eb7e0 r8 = 0x00005568fcc360f0 r9 = 0x0000000000000004 r10 = 0x0000000000000001 r11 = 0x0000000000000001 r12 = 0x000000004d800200 r13 = 0x00007f7140a00710 r14 = 0x00000000009b0004 r15 = 0x00005568fc261c70 AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /src/repro/xlnt/source/detail/cryptography/compound_document.cpp:976:34 in xlnt::detail::compound_document::read_directory() ==46164==ABORTING ``` </details>
Quelle⚠️ https://github.com/xlnt-community/xlnt/issues/141
Benutzer Oneafter (UID 92781)
Einreichung21.02.2026 04:54 (vor 1 Monat)
Moderieren06.03.2026 21:34 (14 days later)
StatusAkzeptiert
VulDB Eintrag349553 [xlnt-community xlnt bis 1.6.1 Encrypted XLSX File Parser compound_document.cpp read_directory Information Disclosure]
Punkte20

Want to know what is going to be exploited?

We predict KEV entries!