Skip to content

Fix buffer overflow in codecForName + normalizeAddressesAndDecodeIdn

Mikhail Khachayants requested to merge tyler/kcodecs:validate-codec into master

The buffer overflow can happen if an invalid codec is passed to normalizeAddressesAndDecodeIdn. There is a necessary check already:

https://github.com/KDE/kcodecs/blob/master/src/kcodecs.cpp#L273-L274

so the missing part is to return nullptr.

Address sanitizer report:

==314938==ERROR: AddressSanitizer: global-buffer-overflow on address 0x555ea45822a8 at pc 0x555ea2a9ccf5 bp 0x7fff4d6bb5f0 sp 0x7fff4d6bb5e8
READ of size 8 at 0x555ea45822a8 thread T0
    #0 0x555ea2a9ccf4 in std::__uniq_ptr_impl<KCodecs::Codec, std::default_delete<KCodecs::Codec>>::_M_ptr() const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:199:51
    #1 0x555ea2a90076 in std::unique_ptr<KCodecs::Codec, std::default_delete<KCodecs::Codec>>::get() const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:470:21
    #2 0x555ea2a85783 in KCodecs::Codec::codecForName(QByteArrayView) KDE/kcodecs/src/kcodecs.cpp:541:24
    #3 0x555ea2a899c8 in KCodecs::parseEncodedWord(char const*&, char const*, QString*, QByteArray*, QByteArray*, QByteArray const&, KCodecs::CharsetOption) KDE/kcodecs/src/kcodecs.cpp:273:20
    #4 0x555ea2a8b8c1 in KCodecs::decodeRFC2047String(QByteArrayView, QByteArray*, QByteArray const&, KCodecs::CharsetOption) KDE/kcodecs/src/kcodecs.cpp:370:17
    #5 0x555ea2a7a217 in KEmailAddress::normalizeAddressesAndDecodeIdn(QString const&) KDE/kcodecs/src/kemailaddress.cpp:1010:27
    #6 0x555ea109560e in LLVMFuzzerTestOneInput KDE/kcodecs/myfuzzing/emailaddress_fuzzer.cc:34:3
    #7 0x555ea0fa1660 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (KDE/kcodecs/myfuzzing/prefix/bin/emailaddress_fuzzer+0x67f660) (BuildId: 1690c881f5f2b287ec56a484393cffd29fe39253)
    #8 0x555ea0f8b7b2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (KDE/kcodecs/myfuzzing/prefix/bin/emailaddress_fuzzer+0x6697b2) (BuildId: 1690c881f5f2b287ec56a484393cffd29fe39253)
    #9 0x555ea0f911f6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (KDE/kcodecs/myfuzzing/prefix/bin/emailaddress_fuzzer+0x66f1f6) (BuildId: 1690c881f5f2b287ec56a484393cffd29fe39253)
    #10 0x555ea0fba362 in main (KDE/kcodecs/myfuzzing/prefix/bin/emailaddress_fuzzer+0x698362) (BuildId: 1690c881f5f2b287ec56a484393cffd29fe39253)
    #11 0x7f9866d32d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #12 0x7f9866d32e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #13 0x555ea0f86794 in _start (KDE/kcodecs/myfuzzing/prefix/bin/emailaddress_fuzzer+0x664794) (BuildId: 1690c881f5f2b287ec56a484393cffd29fe39253)

0x555ea45822a8 is located 24 bytes before global variable 'guard variable for KCodecs::Codec::codecForName(QByteArrayView)::s_codecs' defined in 'KDE/kcodecs/src/kcodecs.cpp' (0x555ea45822c0) of size 8
0x555ea45822a8 is located 8 bytes after global variable 'KCodecs::Codec::codecForName(QByteArrayView)::s_codecs' defined in 'KDE/kcodecs/src/kcodecs.cpp:526' (0x555ea4582240) of size 96
SUMMARY: AddressSanitizer: global-buffer-overflow /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:199:51 in std::__uniq_ptr_impl<KCodecs::Codec, std::default_delete<KCodecs::Codec>>::_M_ptr() const
Shadow bytes around the buggy address:
  0x555ea4582000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582180: 00 00 00 f9 f9 f9 f9 f9 00 f9 f9 f9 00 00 00 00
  0x555ea4582200: 00 00 00 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
=>0x555ea4582280: 00 00 00 00 f9[f9]f9 f9 00 f9 f9 f9 00 00 00 00
  0x555ea4582300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x555ea4582500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==314938==ABORTING

Merge request reports

Loading