Sunday, February 15, 2009

TKADV2009-004 vs. xine-lib

Tomas Hoger from the Red Hat Security Response Team notified me that the 4xm demuxer of xine-lib seems to have the same origin with FFmpeg's version, and is therefore affected by a variant of the bug I described in TKADV2009-004.

xine-lib-1.1.16.1/src/demuxers/demux_4xm.c:

...
192 [1]   const uint32_t current_track = _X_LE_32(&header[i + 8]);
193       if (current_track + 1 > fourxm->track_count) {
194 [2]     fourxm->track_count = current_track + 1;
195 [3]     fourxm->tracks = realloc(fourxm->tracks,
196           fourxm->track_count * sizeof(audio_track_t));
197         if (!fourxm->tracks) {
198           free(header);
199           return 0;
200         }
201       }
...
Unlike FFmpeg, "current_track" is unsigned in xine-lib (see [1]), therefore the exploitation vector described in TKADV2009-004 does not seem directly applicable. However, xine-lib's version of the 4xm demuxer is missing an integer overflow check prior to the allocation of the "fourxm->tracks" buffer (see [2] and [3]).

Tomas also identified a way to exploit this variant of TKADV2009-004: If the first track number is e.g. 0x10000000, a small "fourxm->tracks" array gets allocated in [3]. Subsequent tracks with numbers lower than 0x10000000 will not trigger the array reallocation in [3], but will cause an OOB write.

The bug is fixed in version 1.1.16.2 of xine-lib.

Thanks to Tomas for notification and filing the bug.