Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 626698 (CVE-2017-11550, CVE-2017-11551) - <media-libs/libid3tag-0.16.2: multiple vulnerabilites
Summary: <media-libs/libid3tag-0.16.2: multiple vulnerabilites
Status: IN_PROGRESS
Alias: CVE-2017-11550, CVE-2017-11551
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal minor (vote)
Assignee: Gentoo Security
URL: http://seclists.org/fulldisclosure/20...
Whiteboard: B3 [glsa? cve]
Keywords:
Depends on: 842273 843623
Blocks:
  Show dependency tree
 
Reported: 2017-07-31 13:07 UTC by Christopher Díaz Riveros (RETIRED)
Modified: 2022-05-14 01:48 UTC (History)
5 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
out (out,196 bytes, audio/mpeg)
2022-01-13 06:13 UTC, John Helmert III
no flags Details
fix patch (ucs4-null-pointer-dereference.patch,699 bytes, patch)
2022-04-28 10:27 UTC, kleph
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Christopher Díaz Riveros (RETIRED) gentoo-dev Security 2017-07-31 13:07:57 UTC
From URL:

libid3tag multiple vulnerabilities
================
Author : qflb.wu
===============


Introduction:
=============
Libid3tag is an ID3 tag manipulation library.


Affected version:
=====
0.15.1b


Vulnerability Description:
==========================
1.
the id3_ucs4_length function in ucs4.c in libid3tag 0.15.1b can cause a denial of service(NULL Pointer Dereference and 
application crash) via a crafted mp3 file.


I found this bug when I test mpg321 0.3.2 which used the libid3tag library.


./mpg321 libid3tag_0.15.1b_null_pointer_dereference.mp3


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
id3_ucs4_length (ucs4=ucs4@entry=0x0) at ucs4.c:46
46  while (*ptr)
(gdb) bt
#0  id3_ucs4_length (ucs4=ucs4@entry=0x0) at ucs4.c:46
#1  0x00007ffff76be311 in id3_compat_fixup (tag=tag@entry=0x60400000ce50)
    at compat.gperf:240
#2  0x00007ffff76c069f in v2_parse (ptr=0x61200000b9a1 "") at tag.c:613
#3  id3_tag_parse (data=data@entry=0x61200000b8c0 "ID3\002", 
    length=length@entry=263) at tag.c:665
#4  0x00007ffff76c1504 in read_tag (size=263, iofile=<optimized out>)
    at file.c:103
#5  add_tag (file=file@entry=0x60600000eba0, length=263) at file.c:228
#6  0x00007ffff76c16cb in search_tags (file=0x60600000eba0) at file.c:307
#7  new_file (iofile=iofile@entry=0x61600000de80, 
    mode=mode@entry=ID3_FILE_MODE_READONLY, 
    path=path@entry=0x60400000dfd0 "/home/a/Documents/file") at file.c:407
#8  0x00007ffff76c1890 in id3_file_open (
    path=0x60400000dfd0 "/home/a/Documents/file", 
    mode=ID3_FILE_MODE_READONLY) at file.c:439
#9  0x0000000000485f24 in get_id3_info (fname=<optimized out>, 
    id3struct=<optimized out>, id3tag=<optimized out>) at mpg321.c:485
#10 main (argc=<optimized out>, argv=<optimized out>) at mpg321.c:790
(gdb) 


-------------------
Breakpoint 2, id3_ucs4_length (ucs4=ucs4@entry=0x0) at ucs4.c:46
46  while (*ptr)
(gdb) disassemble 
Dump of assembler code for function id3_ucs4_length:
=> 0x00007ffff76baee0 <+0>:cmpq   $0x0,(%rdi)
   0x00007ffff76baee4 <+4>:je     0x7ffff76baf02 <id3_ucs4_length+34>
   0x00007ffff76baee6 <+6>:mov    %rdi,%rax
   0x00007ffff76baee9 <+9>:nopl   0x0(%rax)
   0x00007ffff76baef0 <+16>:add    $0x8,%rax
   0x00007ffff76baef4 <+20>:cmpq   $0x0,(%rax)
   0x00007ffff76baef8 <+24>:jne    0x7ffff76baef0 <id3_ucs4_length+16>
   0x00007ffff76baefa <+26>:sub    %rdi,%rax
   0x00007ffff76baefd <+29>:sar    $0x3,%rax
   0x00007ffff76baf01 <+33>:retq   
   0x00007ffff76baf02 <+34>:xor    %eax,%eax
   0x00007ffff76baf04 <+36>:retq   
End of assembler dump.
(gdb) i r
rax            0x00
rbx            0x55
rcx            0x00
rdx            0x1016
rsi            0x55
rdi            0x00
rbp            0x7ffff76c329c0x7ffff76c329c
rsp            0x7fffffffb9980x7fffffffb998
r8             0x00
r9             0x7ffff6f7f7b8140737336833976
r10            0x7fffffffb760140737488336736
r11            0x7ffff76bde80140737344429696
r12            0x22
r13            0x6236d06436560
r14            0x6254bc6444220
r15            0x00
rip            0x7ffff76baee00x7ffff76baee0 <id3_ucs4_length>
eflags         0x246[ PF ZF IF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
fs             0x00
---Type <return> to continue, or q <return> to quit---
gs             0x00
(gdb) ni


Program received signal SIGSEGV, Segmentation fault.
id3_ucs4_length (ucs4=ucs4@entry=0x0) at ucs4.c:46
46  while (*ptr)
(gdb) 
--------------------
id3_length_t id3_ucs4_length(id3_ucs4_t const *ucs4)
{
  id3_ucs4_t const *ptr = ucs4;


  while (*ptr)
    ++ptr;


  return ptr - ucs4;
}


POC:
libid3tag_0.15.1b_null_pointer_dereference.mp3
CVE:
CVE-2017-11550


2.
the id3_field_parse function in field.c in libid3tag 0.15.1b can cause a denial of service(OOM) via a crafted mp3 file.


I found this bug when I test mpg321 0.3.2 which used the libid3tag library.


./mpg321 libid3tag_0.15.1b_OOM.mp3


----debug info:----
(gdb) bt
#0  id3_field_parse (field=0x625180, ptr=ptr@entry=0x7fffffffba48, 
    length=<optimized out>, encoding=encoding@entry=0x7fffffffba3c)
    at field.c:306
#1  0x00007ffff76bf10b in parse_data (frame=0x625120, frame=0x625120, 
    length=<optimized out>, data=0x623352 "") at frame.c:252
#2  id3_frame_parse (ptr=ptr@entry=0x7fffffffbad8, length=length@entry=96, 
    version=<optimized out>) at frame.c:464
#3  0x00007ffff76c03c4 in v2_parse (ptr=0x623353 "TT1") at tag.c:607
#4  id3_tag_parse (data=data@entry=0x623290 "ID3\002", length=length@entry=263)
    at tag.c:665
#5  0x00007ffff76c1504 in read_tag (size=263, iofile=<optimized out>)
    at file.c:103
#6  add_tag (file=file@entry=0x62b7f0, length=263) at file.c:228
#7  0x00007ffff76c16cb in search_tags (file=0x62b7f0) at file.c:307
#8  new_file (iofile=iofile@entry=0x623450, 
    mode=mode@entry=ID3_FILE_MODE_READONLY, 
    path=path@entry=0x623040 "/home/a/Documents/file")
    at file.c:407
#9  0x00007ffff76c1890 in id3_file_open (
    path=path@entry=0x623040 "/home/a/Documents/file", 
    mode=mode@entry=ID3_FILE_MODE_READONLY) at file.c:439
#10 0x00000000004053c9 in get_id3_info (
    fname=fname@entry=0x623040 "/home/a/Documents/file",
    ---Type <return> to continue, or q <return> to quit---
 id3struct=id3struct@entry=0x7fffffffbd08, id3tag=id3tag@entry=0x7fffffffbd10)
    at mpg321.c:485
#11 0x0000000000403eae in main (argc=<optimized out>, argv=<optimized out>)
    at mpg321.c:790
(gdb) r
Program terminated with signal SIGKILL, Killed.


----------------
##in field.c id3_field_parse function line:294 ==> line:308
      while (end - *ptr > 0) {
ucs4 = id3_parse_string(ptr, end - *ptr, *encoding, 0);
if (ucs4 == 0)
  goto fail;


strings = realloc(field->stringlist.strings,
 (field->stringlist.nstrings + 1) * sizeof(*strings));
if (strings == 0) {
  free(ucs4);
  goto fail;
}


field->stringlist.strings = strings;
field->stringlist.strings[field->stringlist.nstrings++] = ucs4;
}
Comment 1 Yury German Gentoo Infrastructure gentoo-dev 2019-04-27 18:32:38 UTC
RedHat has this as will not fix: https://access.redhat.com/security/cve/cve-2017-11550
Maintainer(s) please advise on this.
Comment 2 John Helmert III gentoo-dev Security 2020-06-30 03:55:10 UTC
Can't reproduce either issue.
Comment 3 Miroslav Šulc gentoo-dev 2021-04-29 06:38:28 UTC
i could not reproduce any of the issues so you can proceed.

$ equery list libid3tag
 * Searching for libid3tag ...
[IP-] [  ] media-libs/libid3tag-0.15.1b-r4:0
Comment 4 John Helmert III gentoo-dev Security 2021-05-20 22:03:51 UTC
Closing as invalid like the other. Thanks!
Comment 5 Michael Moon 2021-10-06 05:12:36 UTC
I just ran into this today with libid3tag-0.16.1 - backtrace is slightly different but it's still throwing segfault/null pointer dereference in id3_ucs4_length while reading a file.
Comment 6 John Helmert III gentoo-dev Security 2021-10-06 15:51:17 UTC
(In reply to Michael Moon from comment #5)
> I just ran into this today with libid3tag-0.16.1 - backtrace is slightly
> different but it's still throwing segfault/null pointer dereference in
> id3_ucs4_length while reading a file.

With what file?
Comment 7 Marcel Sondaar 2021-12-20 14:55:28 UTC
I ran into this problem as well, so hopefully I can provide the necessary information to resolve this problem. In total I have 188 files that I had to exclude from my collection for causing segfaults when being imported into mpd. 

mp3 file: http://files.combuster.nl/tchaikovsky-the-nutcracker-suite.mp3 (will be taken down later due to fair use and copyright concerns)
compiled mpd: http://files.combuster.nl/mpd
compiled libid3tag: http://files.combuster.nl/libid3tag.so.0.16.1

stacktrace
================
(...)
client: [0] process command "lsinfo "streams/mp3""
client: [0] command returned 0
update: reading streams/mp3/Tchaikovsky - The Nutcracker Suite.mp3

Thread 9 "update" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeddaf640 (LWP 18749)]
id3_ucs4_length (ucs4=ucs4@entry=0x0) at /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1/ucs4.c:42
42      /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1/ucs4.c: No such file or directory.
(gdb) bt
#0  id3_ucs4_length (ucs4=ucs4@entry=0x0) at /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1/ucs4.c:42
#1  0x00007ffff5e9ad97 in id3_compat_fixup (tag=tag@entry=0x7fffdc0192d0)
    at /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1_build-abi_x86_64.amd64/compat.gperf:240
#2  0x00007ffff5e9fb28 in v2_parse (ptr=<optimized out>) at /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1/tag.c:609
#3  id3_tag_parse (data=<optimized out>, length=140737183858392) at /var/tmp/portage/media-libs/libid3tag-0.16.1-r1/work/libid3tag-0.16.1/tag.c:661
#4  0x00005555555fe5a4 in MadDecoder::ParseId3(unsigned long, Tag*) (this=0x7fffedd9c220, tagsize=1920, mpd_tag=0x0)
    at ../mpd-0.22.3/src/decoder/plugins/MadDecoderPlugin.cxx:323
#5  0x00005555555fea8e in MadDecoder::DecodeNextFrame(bool, Tag*) (this=this@entry=0x7fffedd9c220, skip=skip@entry=false, tag=tag@entry=0x0)
    at ../mpd-0.22.3/src/decoder/plugins/MadDecoderPlugin.cxx:405
#6  0x00005555555feae0 in MadDecoder::DecodeFirstFrame(Tag*) (this=this@entry=0x7fffedd9c220, tag=tag@entry=0x0)
    at ../mpd-0.22.3/src/decoder/plugins/MadDecoderPlugin.cxx:696
#7  0x00005555555ff283 in MadDecoder::RunScan(TagHandler&) (handler=..., this=0x7fffedd9c220)
    at ../mpd-0.22.3/src/decoder/plugins/MadDecoderPlugin.cxx:999
#8  mad_decoder_scan_stream(InputStream&, TagHandler&) (is=<optimized out>, handler=...)
    at ../mpd-0.22.3/src/decoder/plugins/MadDecoderPlugin.cxx:1019
#9  0x00005555555ad101 in DecoderPlugin::ScanStream(InputStream&, TagHandler&) const
    (handler=<optimized out>, is=<optimized out>, this=0x55555569ed40 <mad_decoder_plugin>) at ../mpd-0.22.3/src/decoder/DecoderPlugin.hxx:236
#10 TagFileScan::ScanStream(DecoderPlugin const&) (plugin=..., this=0x7fffeddadfe0) at ../mpd-0.22.3/src/TagFile.cxx:64
#11 TagFileScan::Scan(DecoderPlugin const&) (plugin=..., this=0x7fffeddadfe0) at ../mpd-0.22.3/src/TagFile.cxx:69
#12 TagFileScan::Scan(DecoderPlugin const&) (plugin=..., this=0x7fffeddadfe0) at ../mpd-0.22.3/src/TagFile.cxx:67
#13 operator() (plugin=..., __closure=<synthetic pointer>) at ../mpd-0.22.3/src/TagFile.cxx:88
#14 decoder_plugins_try<ScanFileTagsNoGeneric(Path, TagHandler&)::<lambda(const DecoderPlugin&)> > (f=...)
    at ../mpd-0.22.3/src/decoder/DecoderList.hxx:72
--Type <RET> for more, q to quit, c to continue without paging--
#15 ScanFileTagsNoGeneric(Path, TagHandler&) (path_fs=..., handler=<optimized out>) at ../mpd-0.22.3/src/TagFile.cxx:87
#16 0x00005555555ad1ca in ScanFileTagsWithGeneric(Path, TagBuilder&, AudioFormat*)
    (path=..., builder=..., audio_format=audio_format@entry=0x7fffeddae0e8) at ../mpd-0.22.3/src/TagFile.cxx:98
#17 0x00005555555ab08a in Song::UpdateFile(Storage&) (this=0x7fffdc019390, storage=...) at ../mpd-0.22.3/src/util/StringPointer.hxx:52
#18 0x00005555555ab1cf in Song::LoadFile(Storage&, char const*, Directory&) (storage=
    ..., path_utf8=path_utf8@entry=0x7fffdc008e00 "Tchaikovsky - The Nutcracker Suite.mp3", parent=...) at ../mpd-0.22.3/src/SongUpdate.cxx:59
#19 0x000055555560d058 in UpdateWalk::UpdateSongFile2(Directory&, char const*, char const*, StorageFileInfo const&)
    (this=this@entry=0x5555557b7310, directory=..., name=name@entry=0x7fffdc008e00 "Tchaikovsky - The Nutcracker Suite.mp3", suffix=suffix@entry=0x7fffdc008e23 "mp3", info=...) at ../mpd-0.22.3/src/db/update/UpdateSong.cxx:65
#20 0x000055555560d360 in UpdateWalk::UpdateSongFile(Directory&, char const*, char const*, StorageFileInfo const&)
    (this=this@entry=0x5555557b7310, directory=..., name=name@entry=0x7fffdc008e00 "Tchaikovsky - The Nutcracker Suite.mp3", suffix=suffix@entry=0x7fffdc008e23 "mp3", info=...) at ../mpd-0.22.3/src/db/update/UpdateSong.cxx:107
#21 0x000055555560c934 in UpdateWalk::UpdateRegularFile(Directory&, char const*, StorageFileInfo const&)
    (info=..., name=0x7fffdc008e00 "Tchaikovsky - The Nutcracker Suite.mp3", directory=..., this=0x5555557b7310)
    at ../mpd-0.22.3/src/db/update/Walk.cxx:196
#22 UpdateWalk::UpdateDirectoryChild(Directory&, ExcludeList const&, char const*, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=..., name=0x7fffdc008e00 "Tchaikovsky - The Nutcracker Suite.mp3", info=...)
    at ../mpd-0.22.3/src/db/update/Walk.cxx:209
#23 0x000055555560c59e in UpdateWalk::UpdateDirectory(Directory&, ExcludeList const&, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=<optimized out>, info=...) at ../mpd-0.22.3/src/db/update/Walk.cxx:373
#24 0x000055555560c899 in UpdateWalk::UpdateDirectoryChild(Directory&, ExcludeList const&, char const*, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=..., name=0x7fffdc009098 "mp3", info=...) at ../mpd-0.22.3/src/db/update/Walk.cxx:223
#25 0x000055555560c59e in UpdateWalk::UpdateDirectory(Directory&, ExcludeList const&, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=<optimized out>, info=...) at ../mpd-0.22.3/src/db/update/Walk.cxx:373
#26 0x000055555560c899 in UpdateWalk::UpdateDirectoryChild(Directory&, ExcludeList const&, char const*, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=..., name=0x7fffdc008ff0 "streams", info=...) at ../mpd-0.22.3/src/db/update/Walk.cxx:223
#27 0x000055555560c59e in UpdateWalk::UpdateDirectory(Directory&, ExcludeList const&, StorageFileInfo const&)
    (this=0x5555557b7310, directory=..., exclude_list=<optimized out>, info=...) at ../mpd-0.22.3/src/db/update/Walk.cxx:373
#28 0x000055555560cd9a in UpdateWalk::Walk(Directory&, char const*, bool)
    (this=0x5555557b7310, root=..., path=<optimized out>, discard=<optimized out>) at ../mpd-0.22.3/src/db/update/Walk.cxx:498
#29 0x000055555560a156 in UpdateService::Task() (this=0x55555571d1b0) at ../mpd-0.22.3/src/db/plugins/simple/SimpleDatabasePlugin.hxx:85
#30 0x00005555555c4193 in BoundMethod<void () noexcept>::operator()() const (this=0x55555571d200) at ../mpd-0.22.3/src/util/BindMethod.hxx:90
#31 Thread::Run() (this=0x55555571d200) at ../mpd-0.22.3/src/thread/Thread.cxx:63
#32 Thread::ThreadProc(void*) (ctx=0x55555571d200) at ../mpd-0.22.3/src/thread/Thread.cxx:92
#33 0x00007ffff5714d4e in start_thread () at /lib64/libpthread.so.0
#34 0x00007ffff564afaf in clone () at /lib64/libc.so.6
(gdb)
================
Comment 8 Brian S. Stephan 2021-12-29 23:23:17 UTC
I have also seen this recently via mpd. Slightly different stacktrace but the segfault is in id3_ucs4_length, same as above.

File in question can be found at https://ocrmirror.org/files/music/remixes/Castlevania_Bloodlines_Unintentional_OC_ReMix.mp3
Comment 9 Brian S. Stephan 2022-01-13 05:36:22 UTC
Same bug also crashes EasyTAG on the same file, FWIW.
Comment 10 John Helmert III gentoo-dev Security 2022-01-13 06:11:23 UTC
Well, I'm hitting CVE-2017-11550 through MPD.

https://github.com/tenacityteam/libid3tag/issues/6

There is a patch here to fix it (works for me): https://github.com/tenacityteam/libid3tag/pull/7
Comment 11 John Helmert III gentoo-dev Security 2022-01-13 06:13:37 UTC
Created attachment 762005 [details]
out

Attached an afl-minimized test case.
Comment 12 Brian S. Stephan 2022-01-13 13:51:05 UTC
Incidentally (before refreshing this bug and seeing that pull request from tenacityteam) I slapped up a patch that fixed my issues, it is the same as the compat.c change linked above.
Comment 13 Marc Joliet 2022-04-03 14:54:36 UTC
(In reply to John Helmert III from comment #10)
> Well, I'm hitting CVE-2017-11550 through MPD.
My MPD instance was also SEGFAULT-ing in id3_ucs4_length(), but I was able to work around it by reinstalling MPD with USE="-mad", oddly enough, which allowed a database update to complete.  I had moved the root file system to a new drive and was trying to generate the DB from scratch, and before the workaround MPD was repeatedly SEGFAULT-ing at the same file.

Note that I'm not sure why the workaround helped.  I guess libmad calls libid3tag (or vice versa? or something else?) and removing libmad avoids a buggy code path, but neither ebuild depends on the other, so maybe it's specific to how MPD uses them.  Also odd is that based on some of the log output MPD is using ffmpeg for decoding MP3s even with USE="mad".  Whatever, I don't know enough about any of these code bases to understand what's happening :-/ .

In any case, I don't personally care so much about the security aspect of this, but I find it really annoying to have software crashing and having to figure out a workaround.
Comment 14 kleph 2022-04-28 10:27:14 UTC
Created attachment 775146 [details, diff]
fix patch

I just made the patchfile for myself from the github PR mentionned earlier, so I'm uploading here for easy access to others people, since the PR is still not merged.

Tested by placing the file in /etc/portage/patches/media-libs/libid3tag-0.16.1-r1/
Comment 15 John Helmert III gentoo-dev Security 2022-05-03 02:44:23 UTC
Upstream fix is merged
Comment 16 Michael Moon 2022-05-03 02:46:32 UTC
https://github.com/tenacityteam/libid3tag/pull/7 has been merged, I've asked if they'll drop a new release - hopefully this 5 year old issue can be closed with a version bump soon :)
Comment 17 Michael Moon 2022-05-03 04:01:52 UTC
Version bump @ bug 842273
Comment 18 John Helmert III gentoo-dev Security 2022-05-10 16:02:03 UTC
Please stable when ready
Comment 19 Larry the Git Cow gentoo-dev 2022-05-11 06:00:23 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=54cefb43b5930d180027b1689ab769c21538f31c

commit 54cefb43b5930d180027b1689ab769c21538f31c
Author:     Miroslav Šulc <fordfrog@gentoo.org>
AuthorDate: 2022-05-11 06:00:12 +0000
Commit:     Miroslav Šulc <fordfrog@gentoo.org>
CommitDate: 2022-05-11 06:00:20 +0000

    media-libs/libid3tag: dropped obsolete and vulnerable 0.16.1-r1
    
    Bug: https://bugs.gentoo.org/843623
    Bug: https://bugs.gentoo.org/626698
    Signed-off-by: Miroslav Šulc <fordfrog@gentoo.org>

 media-libs/libid3tag/Manifest                   |  1 -
 media-libs/libid3tag/libid3tag-0.16.1-r1.ebuild | 17 -----------------
 2 files changed, 18 deletions(-)
Comment 20 Miroslav Šulc gentoo-dev 2022-05-11 06:01:05 UTC
the tree is clean now, you can proceed.