https://bugs.kde.org/show_bug.cgi?id=525967

            Bug ID: 525967
           Summary: Heap read past TNEF and MAPI strings
    Classification: Applications
           Product: ktnef
      Version First unspecified
       Reported In:
          Platform: Compiled Sources
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Created attachment 196382
  --> https://bugs.kde.org/attachment.cgi?id=196382&action=edit
tnef that causes the crash

DESCRIPTION

**Impact:** A crafted TNEF attribute can crash any consumer that parses it. The
same read can copy adjacent heap bytes into a parsed string. This is a one-byte
ASan-confirmed read.

**Trigger and evidence:** `cases/subject_nonul.tnef` is an 18-byte TNEF file
with a one-byte, non-NUL subject. Run `ASAN_OPTIONS=detect_leaks=0
/tmp/ktnef_repro_asan parse findings/repro/cases/subject_nonul.tnef`. ASan
reports `heap-buffer-overflow`, `READ of size 1`, at `readMAPIString` line 759,
called by `decodeMessage` line 210. The allocation is exactly one byte at line
749. The full trace is in
[string_oob.asan.txt](repro/logs/string_oob.asan.txt).

**Root cause:** ktnefparser.cpp:749 allocates exactly the declared length, then
passes its pointer to `QString::fromLatin1` or `QString::fromUtf16` without a
length. Both conversions search for a terminator beyond the allocation when
none is present. The return value of `readRawData` is also ignored, so a
truncated string can leave uninitialized bytes in that allocation. This helper
is reached from message attributes, attachment titles, and MAPI properties.

**Fix direction:** Check the declared length against the remaining attribute
data and the actual read count. Convert with an explicit length, handling a
trailing terminator only if it lies inside the buffer.

STEPS TO REPRODUCE
1.  Compule ktnef with asan
2.  Write small C reproducer to load this ktnef file
3.  Witness crash

OBSERVED RESULT

```
org.kde.pim.ktnef: Attachment cross reference key: 0x0000
=================================================================
==41137==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x722d519e07b1 at pc 0x62f29aefd81f bp 0x7ffca6cbc610 sp 0x7ffca6cbc608
READ of size 1 at 0x722d519e07b1 thread T0
    #0 0x62f29aefd81e in long long QtPrivate::lengthHelperPointer<char>(char
const*) /usr/include/x86_64-linux-gnu/qt6/QtCore/qbytearrayview.h:78:12
    #1 0x62f29aefd81e in QByteArrayView::QByteArrayView<char*, true>(char*
const&) /usr/include/x86_64-linux-gnu/qt6/QtCore/qbytearrayview.h:162:28
    #2 0x62f29aeede78 in readMAPIString(QDataStream&, bool, bool, int)
/home/fuzz/ktnef/src/ktnefparser.cpp:759:35
    #3 0x62f29aeeaef8 in KTnef::ParserPrivate::decodeMessage()
/home/fuzz/ktnef/src/ktnefparser.cpp:210:17
    #4 0x62f29aef73fe in KTnef::ParserPrivate::parseDevice()
/home/fuzz/ktnef/src/ktnefparser.cpp:415:22
    #5 0x62f29af151f1 in main /tmp/ktnef-audit/harness.cpp:26:15
    #6 0x760d5502a600 in __libc_start_call_main
csu/../sysdeps/nptl/libc_start_call_main.h:59:16
    #7 0x760d5502a717 in __libc_start_main csu/../csu/libc-start.c:360:3
    #8 0x62f29adfdbc4 in _start (/tmp/ktnef-audit/ktnef_asan+0x41bc4) (BuildId:
e8d138fb80df82076c679d970e73cd14feefcc55)

0x722d519e07b1 is located 0 bytes after 1-byte region
[0x722d519e07b0,0x722d519e07b1)
allocated by thread T0 here:
    #0 0x62f29aee74b1 in operator new[](unsigned long)
(/tmp/ktnef-audit/ktnef_asan+0x12b4b1) (BuildId:
e8d138fb80df82076c679d970e73cd14feefcc55)
    #1 0x62f29aeedd27 in readMAPIString(QDataStream&, bool, bool, int)
/home/fuzz/ktnef/src/ktnefparser.cpp:749:11
    #2 0x62f29aeeaef8 in KTnef::ParserPrivate::decodeMessage()
/home/fuzz/ktnef/src/ktnefparser.cpp:210:17
    #3 0x62f29aef73fe in KTnef::ParserPrivate::parseDevice()
/home/fuzz/ktnef/src/ktnefparser.cpp:415:22
    #4 0x62f29af151f1 in main /tmp/ktnef-audit/harness.cpp:26:15
    #5 0x760d5502a600 in __libc_start_call_main
csu/../sysdeps/nptl/libc_start_call_main.h:59:16
    #6 0x760d5502a717 in __libc_start_main csu/../csu/libc-start.c:360:3
    #7 0x62f29adfdbc4 in _start (/tmp/ktnef-audit/ktnef_asan+0x41bc4) (BuildId:
e8d138fb80df82076c679d970e73cd14feefcc55)

SUMMARY: AddressSanitizer: heap-buffer-overflow
/usr/include/x86_64-linux-gnu/qt6/QtCore/qbytearrayview.h:78:12 in long long
QtPrivate::lengthHelperPointer<char>(char const*)
Shadow bytes around the buggy address:
  0x722d519e0500: fa fa 07 fa fa fa 00 fa fa fa fd fa fa fa fd fa
  0x722d519e0580: fa fa 07 fa fa fa 00 fa fa fa fd fa fa fa fd fa
  0x722d519e0600: fa fa 07 fa fa fa 00 fa fa fa 00 fa fa fa 00 00
  0x722d519e0680: fa fa fd fd fa fa fd fd fa fa 00 fa fa fa fd fd
  0x722d519e0700: fa fa fd fd fa fa 00 00 fa fa 00 00 fa fa 00 00
=>0x722d519e0780: fa fa 00 00 fa fa[01]fa fa fa fa fa fa fa fa fa
  0x722d519e0800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x722d519e0880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x722d519e0900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x722d519e0980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x722d519e0a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==41137==ABORTING
```

EXPECTED RESULT

No crash.

SOFTWARE/OS VERSIONS
Operating System: Ubuntu 26.04
KDE Plasma Version:  not applicable
KDE Frameworks Version:  not applicable
Qt Version: 6

ADDITIONAL INFORMATION

This was a compiled source ktnef with latest commit:
2f0f59ceb9163f77cfb1e195777482674cedd88f

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to