Version in base suite: 1.31.2-1 Base version: mpg123_1.31.2-1 Target version: mpg123_1.31.2-1+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/m/mpg123/mpg123_1.31.2-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/m/mpg123/mpg123_1.31.2-1+deb12u1.dsc changelog | 8 patches/CVE-2024-10573.patch | 946 +++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 955 insertions(+) diff -Nru mpg123-1.31.2/debian/changelog mpg123-1.31.2/debian/changelog --- mpg123-1.31.2/debian/changelog 2023-01-19 22:10:37.000000000 +0000 +++ mpg123-1.31.2/debian/changelog 2024-11-10 15:26:42.000000000 +0000 @@ -1,3 +1,11 @@ +mpg123 (1.31.2-1+deb12u1) bookworm-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Fix buffer overflow (Frankenstein's Monster) (CVE-2024-10573) + (Closes: #1086443) + + -- Salvatore Bonaccorso Sun, 10 Nov 2024 16:26:42 +0100 + mpg123 (1.31.2-1) unstable; urgency=medium * New upstream version 1.31.2 diff -Nru mpg123-1.31.2/debian/patches/CVE-2024-10573.patch mpg123-1.31.2/debian/patches/CVE-2024-10573.patch --- mpg123-1.31.2/debian/patches/CVE-2024-10573.patch 1970-01-01 00:00:00.000000000 +0000 +++ mpg123-1.31.2/debian/patches/CVE-2024-10573.patch 2024-11-10 15:26:42.000000000 +0000 @@ -0,0 +1,946 @@ +Description: Fix buffer overflow (Frankenstein's Monster) (CVE-2024-10573) +Origin: upstream, https://scm.orgis.org/mpg123/branches/1.31-fixes/ +Bug: https://mpg123.org/bugs/322 +Bug-Debian: https://bugs.debian.org/1086443 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2024-10573 +Forwarded: not-needed +Last-Update: 2024-11-10 +Applied-Upstream: 1.31.4 + +--- a/src/libmpg123/frame.c ++++ b/src/libmpg123/frame.c +@@ -515,6 +515,7 @@ static void frame_fixed_reset(mpg123_han + { + frame_icy_reset(fr); + open_bad(fr); ++ memset(&(fr->hdr), 0, sizeof(fr->hdr)); + fr->to_decode = FALSE; + fr->to_ignore = FALSE; + fr->metaflags = 0; +@@ -528,15 +529,12 @@ static void frame_fixed_reset(mpg123_han + fr->clip = 0; + fr->oldhead = 0; + fr->firsthead = 0; +- fr->lay = 0; + fr->vbr = MPG123_CBR; + fr->abr_rate = 0; + fr->track_frames = 0; + fr->track_samples = -1; +- fr->framesize=0; + fr->mean_frames = 0; + fr->mean_framesize = 0; +- fr->freesize = 0; + fr->lastscale = -1; + fr->rva.level[0] = -1; + fr->rva.level[1] = -1; +@@ -571,8 +569,7 @@ static void frame_fixed_reset(mpg123_han + fr->icy.next = 0; + #endif + fr->halfphase = 0; /* here or indeed only on first-time init? */ +- fr->error_protection = 0; +- fr->freeformat_framesize = fr->p.freeformat_framesize; ++ fr->hdr.freeformat_framesize = fr->p.freeformat_framesize; + fr->enc_delay = -1; + fr->enc_padding = -1; + memset(fr->id3buf, 0, sizeof(fr->id3buf)); +@@ -637,7 +634,7 @@ int attribute_align_arg mpg123_framedata + + if(header != NULL) *header = mh->oldhead; + if(bodydata != NULL) *bodydata = mh->bsbuf; +- if(bodybytes != NULL) *bodybytes = mh->framesize; ++ if(bodybytes != NULL) *bodybytes = mh->hdr.framesize; + + return MPG123_OK; + } +@@ -906,9 +903,9 @@ static off_t ignoreframe(mpg123_handle * + { + off_t preshift = fr->p.preframes; + /* Layer 3 _really_ needs at least one frame before. */ +- if(fr->lay==3 && preshift < 1) preshift = 1; ++ if(fr->hdr.lay==3 && preshift < 1) preshift = 1; + /* Layer 1 & 2 reall do not need more than 2. */ +- if(fr->lay!=3 && preshift > 2) preshift = 2; ++ if(fr->hdr.lay!=3 && preshift > 2) preshift = 2; + + return fr->firstframe - preshift; + } +@@ -953,7 +950,7 @@ void frame_set_frameseek(mpg123_handle * + void frame_skip(mpg123_handle *fr) + { + #ifndef NO_LAYER3 +- if(fr->lay == 3) set_pointer(fr, 1, 512); ++ if(fr->hdr.lay == 3) set_pointer(fr, 1, 512); + #endif + } + +--- a/src/libmpg123/frame.h ++++ b/src/libmpg123/frame.h +@@ -96,6 +96,33 @@ enum frame_state_flags + ,FRAME_DECODER_LIVE = 0x8 /**< 1000 Decoder can be used. */ + }; + ++// separate frame header structure for safe decoding of headers without ++// modifying the main frame struct before we are sure that we can read a ++// frame into it ++struct frame_header ++{ ++ int lay; ++ // lots of flags that could share storage, should reform that ++ int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */ ++ int mpeg25; ++ int error_protection; ++ int bitrate_index; ++ int sampling_frequency; ++ int padding; ++ int extension; ++ int mode; ++ int mode_ext; ++ int copyright; ++ int original; ++ int emphasis; ++ // Even 16 bit int is enough for MAXFRAMESIZE ++ int framesize; /* computed framesize */ ++ int freeformat; ++ int freeformat_framesize; ++ // Derived from header and checked against the above. ++ int ssize; ++}; ++ + /* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */ + struct mpg123_handle_struct + { +@@ -199,26 +226,12 @@ struct mpg123_handle_struct + int single; + int II_sblimit; + int down_sample_sblimit; +- int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */ + /* Many flags in disguise as integers... wasting bytes. */ +- int mpeg25; + int down_sample; + int header_change; +- int lay; ++ struct frame_header hdr; + long spf; /* cached count of samples per frame */ + int (*do_layer)(mpg123_handle *); +- int error_protection; +- int bitrate_index; +- int sampling_frequency; +- int padding; +- int extension; +- int mode; +- int mode_ext; +- int copyright; +- int original; +- int emphasis; +- int framesize; /* computed framesize */ +- int freesize; /* free format frame size */ + enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */ + off_t num; /* frame offset ... */ + off_t input_offset; /* byte offset of this frame in input stream */ +@@ -227,8 +240,6 @@ struct mpg123_handle_struct + int state_flags; + char silent_resync; /* Do not complain for the next n resyncs. */ + unsigned char* xing_toc; /* The seek TOC from Xing header. */ +- int freeformat; +- long freeformat_framesize; + + /* bitstream info; bsi */ + int bitindex; +@@ -255,7 +266,6 @@ struct mpg123_handle_struct + double mean_framesize; + off_t mean_frames; + int fsizeold; +- int ssize; + unsigned int bitreservoir; + unsigned char bsspace[2][MAXFRAMESIZE+512+4]; /* MAXFRAMESIZE */ + unsigned char *bsbuf; +--- a/src/libmpg123/layer1.c ++++ b/src/libmpg123/layer1.c +@@ -217,7 +217,7 @@ int do_layer1(mpg123_handle *fr) + real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* fraction[2][SBLIMIT] */ + int single = fr->single; + +- fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32; ++ fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : 32; + + if(stereo == 1 || single == SINGLE_MIX) /* I don't see mixing handled here */ + single = SINGLE_LEFT; +--- a/src/libmpg123/layer2.c ++++ b/src/libmpg123/layer2.c +@@ -313,10 +313,10 @@ static void II_select_table(mpg123_handl + const struct al_table *tables[5] = { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 }; + const int sblims[5] = { 27 , 30 , 8, 12 , 30 }; + +- if(fr->sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */ ++ if(fr->hdr.sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */ + table = 4; + else +- table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index]; ++ table = translate[fr->hdr.sampling_frequency][2-fr->stereo][fr->hdr.bitrate_index]; + + sblim = sblims[table]; + fr->alloc = tables[table]; +@@ -337,7 +337,7 @@ int do_layer2(mpg123_handle *fr) + int single = fr->single; + + II_select_table(fr); +- fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : fr->II_sblimit; ++ fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : fr->II_sblimit; + + if(fr->jsbound > fr->II_sblimit) + { +--- a/src/libmpg123/layer3.c ++++ b/src/libmpg123/layer3.c +@@ -127,16 +127,16 @@ static int III_get_side_info(mpg123_hand + int powdiff = (single == SINGLE_MIX) ? 4 : 0; + + const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } }; +- const int *tab = tabs[fr->lsf]; ++ const int *tab = tabs[fr->hdr.lsf]; + + { /* First ensure we got enough bits available. */ + unsigned int needbits = 0; + needbits += tab[1]; /* main_data_begin */ + needbits += stereo == 1 ? tab[2] : tab[3]; /* private */ +- if(!fr->lsf) ++ if(!fr->hdr.lsf) + needbits += stereo*4; /* scfsi */ + /* For each granule for each channel ... */ +- needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->lsf?1:0)+2); ++ needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->hdr.lsf?1:0)+2); + if(fr->bits_avail < needbits) \ + { + if(NOQUIET) +@@ -154,7 +154,7 @@ static int III_get_side_info(mpg123_hand + + /* overwrite main_data_begin for the really available bit reservoir */ + backbits(fr, tab[1]); +- if(fr->lsf == 0) ++ if(fr->hdr.lsf == 0) + { + fr->wordpointer[0] = (unsigned char) (fr->bitreservoir >> 1); + fr->wordpointer[1] = (unsigned char) ((fr->bitreservoir & 1) << 7); +@@ -163,7 +163,7 @@ static int III_get_side_info(mpg123_hand + + /* zero "side-info" data for a silence-frame + without touching audio data used as bit reservoir for following frame */ +- memset(fr->wordpointer+2, 0, fr->ssize-2); ++ memset(fr->wordpointer+2, 0, fr->hdr.ssize-2); + + /* reread the new bit reservoir offset */ + si->main_data_begin = getbits(fr, tab[1]); +@@ -171,11 +171,11 @@ static int III_get_side_info(mpg123_hand + + /* Keep track of the available data bytes for the bit reservoir. + CRC is included in ssize already. */ +- fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize; ++ fr->bitreservoir = fr->bitreservoir + fr->hdr.framesize - fr->hdr.ssize; + + /* Limit the reservoir to the max for MPEG 1.0 or 2.x . */ +- if(fr->bitreservoir > (unsigned int) (fr->lsf == 0 ? 511 : 255)) +- fr->bitreservoir = (fr->lsf == 0 ? 511 : 255); ++ if(fr->bitreservoir > (unsigned int) (fr->hdr.lsf == 0 ? 511 : 255)) ++ fr->bitreservoir = (fr->hdr.lsf == 0 ? 511 : 255); + + /* Now back into less commented territory. It's code. It works. */ + +@@ -184,7 +184,7 @@ static int III_get_side_info(mpg123_hand + else + si->private_bits = getbits(fr, tab[3]); + +- if(!fr->lsf) for(ch=0; chhdr.lsf) for(ch=0; chch[ch].gr[0].scfsi = -1; + si->ch[ch].gr[1].scfsi = getbits(fr, 4); +@@ -249,14 +249,14 @@ static int III_get_side_info(mpg123_hand + } + + /* region_count/start parameters are implicit in this case. */ +- if( (!fr->lsf || (gr_info->block_type == 2)) && !fr->mpeg25) ++ if( (!fr->hdr.lsf || (gr_info->block_type == 2)) && !fr->hdr.mpeg25) + { + gr_info->region1start = 36>>1; + gr_info->region2start = 576>>1; + } + else + { +- if(fr->mpeg25) ++ if(fr->hdr.mpeg25) + { + int r0c,r1c; + if((gr_info->block_type == 2) && (!gr_info->mixed_block_flag) ) r0c = 5; +@@ -291,7 +291,7 @@ static int III_get_side_info(mpg123_hand + gr_info->block_type = 0; + gr_info->mixed_block_flag = 0; + } +- if(!fr->lsf) gr_info->preflag = get1bit(fr); ++ if(!fr->hdr.lsf) gr_info->preflag = get1bit(fr); + + gr_info->scalefac_scale = get1bit(fr); + gr_info->count1table_select = get1bit(fr); +@@ -1717,7 +1717,7 @@ int do_layer3(mpg123_handle *fr) + int stereo = fr->stereo; + int single = fr->single; + int ms_stereo,i_stereo; +- int sfreq = fr->sampling_frequency; ++ int sfreq = fr->hdr.sampling_frequency; + int stereo1,granules; + + if(stereo == 1) +@@ -1730,14 +1730,14 @@ int do_layer3(mpg123_handle *fr) + else + stereo1 = 2; + +- if(fr->mode == MPG_MD_JOINT_STEREO) ++ if(fr->hdr.mode == MPG_MD_JOINT_STEREO) + { +- ms_stereo = (fr->mode_ext & 0x2)>>1; +- i_stereo = fr->mode_ext & 0x1; ++ ms_stereo = (fr->hdr.mode_ext & 0x2)>>1; ++ i_stereo = fr->hdr.mode_ext & 0x1; + } + else ms_stereo = i_stereo = 0; + +- granules = fr->lsf ? 1 : 2; ++ granules = fr->hdr.lsf ? 1 : 2; + + /* quick hack to keep the music playing */ + /* after having seen this nasty test file... */ +@@ -1752,7 +1752,7 @@ int do_layer3(mpg123_handle *fr) + if(fr->pinfo) + { + fr->pinfo->maindata = sideinfo.main_data_begin; +- fr->pinfo->padding = fr->padding; ++ fr->pinfo->padding = fr->hdr.padding; + } + #endif + for(gr=0;grpart2_3_length, fr->bits_avail ); + return clip; + } +- if(fr->lsf) ++ if(fr->hdr.lsf) + part2bits = III_get_scale_factors_2(fr, scalefacs[0],gr_info,0); + else + part2bits = III_get_scale_factors_1(fr, scalefacs[0],gr_info,0,gr); +@@ -1813,7 +1813,7 @@ int do_layer3(mpg123_handle *fr) + { + struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); + long part2bits; +- if(fr->lsf) ++ if(fr->hdr.lsf) + part2bits = III_get_scale_factors_2(fr, scalefacs[1],gr_info,i_stereo); + else + part2bits = III_get_scale_factors_1(fr, scalefacs[1],gr_info,1,gr); +@@ -1863,7 +1863,7 @@ int do_layer3(mpg123_handle *fr) + } + } + +- if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->lsf); ++ if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->hdr.lsf); + + if(ms_stereo || i_stereo || (single == SINGLE_MIX) ) + { +--- a/src/libmpg123/libmpg123.c ++++ b/src/libmpg123/libmpg123.c +@@ -434,7 +434,7 @@ int attribute_align_arg mpg123_getstate( + theval = mh->enc_padding; + break; + case MPG123_DEC_DELAY: +- theval = mh->lay == 3 ? GAPLESS_DELAY : -1; ++ theval = mh->hdr.lay == 3 ? GAPLESS_DELAY : -1; + break; + default: + mh->err = MPG123_BAD_KEY; +@@ -1187,10 +1187,10 @@ static int init_track(mpg123_handle *mh) + b = init_track(mh); \ + if(b < 0) return b; \ + \ +- mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0); \ +- mi->layer = mh->lay; \ ++ mi->version = mh->hdr.mpeg25 ? MPG123_2_5 : (mh->hdr.lsf ? MPG123_2_0 : MPG123_1_0); \ ++ mi->layer = mh->hdr.lay; \ + mi->rate = frame_freq(mh); \ +- switch(mh->mode) \ ++ switch(mh->hdr.mode) \ + { \ + case 0: mi->mode = MPG123_M_STEREO; break; \ + case 1: mi->mode = MPG123_M_JOINT; break; \ +@@ -1198,14 +1198,14 @@ static int init_track(mpg123_handle *mh) + case 3: mi->mode = MPG123_M_MONO; break; \ + default: mi->mode = 0; /* Nothing good to do here. */ \ + } \ +- mi->mode_ext = mh->mode_ext; \ +- mi->framesize = mh->framesize+4; /* Include header. */ \ ++ mi->mode_ext = mh->hdr.mode_ext; \ ++ mi->framesize = mh->hdr.framesize+4; /* Include header. */ \ + mi->flags = 0; \ +- if(mh->error_protection) mi->flags |= MPG123_CRC; \ +- if(mh->copyright) mi->flags |= MPG123_COPYRIGHT; \ +- if(mh->extension) mi->flags |= MPG123_PRIVATE; \ +- if(mh->original) mi->flags |= MPG123_ORIGINAL; \ +- mi->emphasis = mh->emphasis; \ ++ if(mh->hdr.error_protection) mi->flags |= MPG123_CRC; \ ++ if(mh->hdr.copyright) mi->flags |= MPG123_COPYRIGHT; \ ++ if(mh->hdr.extension) mi->flags |= MPG123_PRIVATE; \ ++ if(mh->hdr.original) mi->flags |= MPG123_ORIGINAL; \ ++ mi->emphasis = mh->hdr.emphasis; \ + mi->bitrate = frame_bitrate(mh); \ + mi->abr_rate = mh->abr_rate; \ + mi->vbr = mh->vbr; \ +--- a/src/libmpg123/parse.c ++++ b/src/libmpg123/parse.c +@@ -63,9 +63,10 @@ static const int tabsel_123[2][3][16] = + + static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; + +-static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count); +-static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount); +-static int do_readahead(mpg123_handle *fr, unsigned long newhead); ++static int decode_header(mpg123_handle *fr, struct frame_header *hdr, unsigned long newhead, int *freeformat_count); ++static void apply_header(mpg123_handle *fr, struct frame_header *hdr); ++static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr); ++static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead); + static int wetwork(mpg123_handle *fr, unsigned long *newheadp); + + /* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/ +@@ -73,12 +74,12 @@ static int wetwork(mpg123_handle *fr, un + + int frame_bitrate(mpg123_handle *fr) + { +- return tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index]; ++ return tabsel_123[fr->hdr.lsf][fr->hdr.lay-1][fr->hdr.bitrate_index]; + } + + long frame_freq(mpg123_handle *fr) + { +- return freqs[fr->sampling_frequency]; ++ return freqs[fr->hdr.sampling_frequency]; + } + + /* compiler is smart enought to inline this one or should I really do it as macro...? */ +@@ -141,8 +142,8 @@ static int check_lame_tag(mpg123_handle + Mono 17 9 + */ + int lame_offset = (fr->stereo == 2) +- ? (fr->lsf ? 17 : 32) +- : (fr->lsf ? 9 : 17); ++ ? (fr->hdr.lsf ? 17 : 32) ++ : (fr->hdr.lsf ? 9 : 17); + + if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no; + +@@ -154,7 +155,7 @@ static int check_lame_tag(mpg123_handle + for the actual data, have to check if each byte of information is present. + But: 4 B Info/Xing + 4 B flags is bare minimum. + */ +- if(fr->framesize < lame_offset+8) goto check_lame_tag_no; ++ if(fr->hdr.framesize < lame_offset+8) goto check_lame_tag_no; + + /* only search for tag when all zero before it (apart from checksum) */ + for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no; +@@ -190,7 +191,7 @@ static int check_lame_tag(mpg123_handle + + /* From now on, I have to carefully check if the announced data is actually + there! I'm always returning 'yes', though. */ +- #define check_bytes_left(n) if(fr->framesize < lame_offset+n) \ ++ #define check_bytes_left(n) if(fr->hdr.framesize < lame_offset+n) \ + goto check_lame_tag_yes + if(xing_flags & 1) /* total bitstream frames */ + { +@@ -443,10 +444,10 @@ static int head_compatible(unsigned long + static void halfspeed_prepare(mpg123_handle *fr) + { + /* save for repetition */ +- if(fr->p.halfspeed && fr->lay == 3) ++ if(fr->p.halfspeed && fr->hdr.lay == 3) + { + debug("halfspeed - reusing old bsbuf "); +- memcpy (fr->ssave, fr->bsbuf, fr->ssize); ++ memcpy (fr->ssave, fr->bsbuf, fr->hdr.ssize); + } + } + +@@ -462,8 +463,8 @@ static int halfspeed_do(mpg123_handle *f + fr->to_decode = fr->to_ignore = TRUE; + --fr->halfphase; + set_pointer(fr, 0, 0); +- if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize); +- if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ ++ if(fr->hdr.lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->hdr.ssize); ++ if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */ + return 1; + } + else +@@ -496,10 +497,11 @@ int read_frame(mpg123_handle *fr) + /* TODO: rework this thing */ + int freeformat_count = 0; + unsigned long newhead; ++ /* Start with current frame header state as copy for roll-back ability. */ ++ struct frame_header nhdr = fr->hdr; + off_t framepos; + int ret; + /* stuff that needs resetting if complete frame reading fails */ +- int oldsize = fr->framesize; + int oldphase = fr->halfphase; + + /* The counter for the search-first-header loop. +@@ -507,11 +509,12 @@ int read_frame(mpg123_handle *fr) + when repeatedly headers are found that do not have valid followup headers. */ + long headcount = 0; + +- fr->fsizeold=fr->framesize; /* for Layer3 */ ++ fr->fsizeold=fr->hdr.framesize; /* for Layer3 */ + + if(halfspeed_do(fr) == 1) return 1; + + /* From now on, old frame data is tainted by parsing attempts. */ ++ // Handling premature effects of decode_header now, more decoupling would be welcome. + fr->to_decode = fr->to_ignore = FALSE; + + if( fr->p.flags & MPG123_NO_FRANKENSTEIN && +@@ -540,13 +543,13 @@ init_resync: + #ifdef SKIP_JUNK + if(!fr->firsthead && !head_check(newhead)) + { +- ret = skip_junk(fr, &newhead, &headcount); ++ ret = skip_junk(fr, &newhead, &headcount, &nhdr); + JUMP_CONCLUSION(ret); + } + #endif + + ret = head_check(newhead); +- if(ret) ret = decode_header(fr, newhead, &freeformat_count); ++ if(ret) ret = decode_header(fr, &nhdr, newhead, &freeformat_count); + + JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */ + if(ret == PARSE_BAD) +@@ -561,7 +564,7 @@ init_resync: + { + ret = fr->p.flags & MPG123_NO_READAHEAD + ? PARSE_GOOD +- : do_readahead(fr, newhead); ++ : do_readahead(fr, &nhdr, newhead); + /* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */ + if(ret < 0) fr->rd->back_bytes(fr, 4); + JUMP_CONCLUSION(ret); +@@ -585,8 +588,8 @@ init_resync: + { + unsigned char *newbuf = fr->bsspace[fr->bsnum]+512; + /* read main data into memory */ +- debug2("read frame body of %i at %"OFF_P, fr->framesize, framepos+4); +- if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0) ++ debug2("read frame body of %i at %"PRIi64, nhdr.framesize, framepos+4); ++ if((ret=fr->rd->read_frame_body(fr,newbuf,nhdr.framesize))<0) + { + /* if failed: flip back */ + debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error"); +@@ -597,6 +600,10 @@ init_resync: + } + fr->bsnum = (fr->bsnum + 1) & 1; + ++ // We read the frame body, time to apply the matching header. ++ // Even if erroring out later, the header state needs to match the body. ++ apply_header(fr, &nhdr); ++ + if(!fr->firsthead) + { + fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */ +@@ -608,7 +615,7 @@ init_resync: + fr->audio_start = framepos; + /* Only check for LAME tag at beginning of whole stream + ... when there indeed is one in between, it's the user's problem. */ +- if(fr->lay == 3 && check_lame_tag(fr) == 1) ++ if(fr->hdr.lay == 3 && check_lame_tag(fr) == 1) + { /* ...in practice, Xing/LAME tags are layer 3 only. */ + if(fr->rd->forget != NULL) fr->rd->forget(fr); + +@@ -624,6 +631,8 @@ init_resync: + + set_pointer(fr, 0, 0); + ++ // No use of nhdr from here on. It is fr->hdr now! ++ + /* Question: How bad does the floating point value get with repeated recomputation? + Also, considering that we can play the file or parts of many times. */ + if(++fr->mean_frames != 0) +@@ -632,7 +641,7 @@ init_resync: + } + ++fr->num; /* 0 for first frame! */ + debug4("Frame %"OFF_P" %08lx %i, next filepos=%"OFF_P, +- (off_p)fr->num, newhead, fr->framesize, (off_p)fr->rd->tell(fr)); ++ (off_p)fr->num, newhead, fr->hdr.framesize, (off_p)fr->rd->tell(fr)); + if(!(fr->state_flags & FRAME_FRANKENSTEIN) && ( + (fr->track_frames > 0 && fr->num >= fr->track_frames) + #ifdef GAPLESS +@@ -664,7 +673,7 @@ init_resync: + if(fr->rd->forget != NULL) fr->rd->forget(fr); + + fr->to_decode = fr->to_ignore = TRUE; +- if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ ++ if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */ + + /* + Let's check for header change after deciding that the new one is good +@@ -711,7 +720,6 @@ read_frame_bad: + + fr->silent_resync = 0; + if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER; +- fr->framesize = oldsize; + fr->halfphase = oldphase; + /* That return code might be inherited from some feeder action, or reader error. */ + return ret; +@@ -725,9 +733,9 @@ read_frame_bad: + * <0: error codes, possibly from feeder buffer (NEED_MORE) + * PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...) + */ +-static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead) ++static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead, int *framesize) + { +- long i; ++ int i; + int ret; + unsigned long head; + if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED))) +@@ -748,7 +756,7 @@ static int guess_freeformat_framesize(mp + if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK)) + { + fr->rd->back_bytes(fr,i+1); +- fr->framesize = i-3; ++ *framesize = i-3; + return PARSE_GOOD; /* Success! */ + } + } +@@ -765,8 +773,13 @@ static int guess_freeformat_framesize(mp + * 0: no valid header + * <0: some error + * You are required to do a head_check() before calling! ++ * ++ * This now only operates on a frame header struct, not the full frame structure. ++ * The scope is limited to parsing header information and determining the size of ++ * the frame body to read. Everything else belongs into a later stage of applying ++ * header information to the main decoder frame structure. + */ +-static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count) ++static int decode_header(mpg123_handle *fr, struct frame_header *fh, unsigned long newhead, int *freeformat_count) + { + #ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */ + if(!head_check(newhead)) +@@ -777,43 +790,42 @@ static int decode_header(mpg123_handle * + /* For some reason, the layer and sampling freq settings used to be wrapped + in a weird conditional including MPG123_NO_RESYNC. What was I thinking? + This information has to be consistent. */ +- fr->lay = 4 - HDR_LAYER_VAL(newhead); ++ fh->lay = 4 - HDR_LAYER_VAL(newhead); + + if(HDR_VERSION_VAL(newhead) & 0x2) + { +- fr->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1; +- fr->mpeg25 = 0; +- fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3); ++ fh->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1; ++ fh->mpeg25 = 0; ++ fh->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fh->lsf*3); + } + else + { +- fr->lsf = 1; +- fr->mpeg25 = 1; +- fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead); ++ fh->lsf = 1; ++ fh->mpeg25 = 1; ++ fh->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead); + } + + #ifdef DEBUG + /* seen a file where this varies (old lame tag without crc, track with crc) */ +- if((HDR_CRC_VAL(newhead)^0x1) != fr->error_protection) debug("changed crc bit!"); ++ if((HDR_CRC_VAL(newhead)^0x1) != fh->error_protection) debug("changed crc bit!"); + #endif +- fr->error_protection = HDR_CRC_VAL(newhead)^0x1; +- fr->bitrate_index = HDR_BITRATE_VAL(newhead); +- fr->padding = HDR_PADDING_VAL(newhead); +- fr->extension = HDR_PRIVATE_VAL(newhead); +- fr->mode = HDR_CHANNEL_VAL(newhead); +- fr->mode_ext = HDR_CHANEX_VAL(newhead); +- fr->copyright = HDR_COPYRIGHT_VAL(newhead); +- fr->original = HDR_ORIGINAL_VAL(newhead); +- fr->emphasis = HDR_EMPHASIS_VAL(newhead); +- fr->freeformat = !(newhead & HDR_BITRATE); ++ fh->error_protection = HDR_CRC_VAL(newhead)^0x1; ++ fh->bitrate_index = HDR_BITRATE_VAL(newhead); ++ fh->padding = HDR_PADDING_VAL(newhead); ++ fh->extension = HDR_PRIVATE_VAL(newhead); ++ fh->mode = HDR_CHANNEL_VAL(newhead); ++ fh->mode_ext = HDR_CHANEX_VAL(newhead); ++ fh->copyright = HDR_COPYRIGHT_VAL(newhead); ++ fh->original = HDR_ORIGINAL_VAL(newhead); ++ fh->emphasis = HDR_EMPHASIS_VAL(newhead); ++ fh->freeformat = !(newhead & HDR_BITRATE); + +- fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; + + /* we can't use tabsel_123 for freeformat, so trying to guess framesize... */ +- if(fr->freeformat) ++ if(fh->freeformat) + { + /* when we first encounter the frame with freeformat, guess framesize */ +- if(fr->freeformat_framesize < 0) ++ if(fh->freeformat_framesize < 0) + { + int ret; + if(fr->p.flags & MPG123_NO_READAHEAD) +@@ -828,12 +840,12 @@ static int decode_header(mpg123_handle * + if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_."); + return PARSE_BAD; + } +- ret = guess_freeformat_framesize(fr, newhead); ++ ret = guess_freeformat_framesize(fr, newhead, &(fh->framesize)); + if(ret == PARSE_GOOD) + { +- fr->freeformat_framesize = fr->framesize - fr->padding; ++ fh->freeformat_framesize = fh->framesize - fh->padding; + if(VERBOSE2) +- fprintf(stderr, "Note: free format frame size %li\n", fr->freeformat_framesize); ++ fprintf(stderr, "Note: free format frame size %i\n", fh->freeformat_framesize); + } + else + { +@@ -848,81 +860,110 @@ static int decode_header(mpg123_handle * + /* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */ + else + { +- fr->framesize = fr->freeformat_framesize + fr->padding; ++ fh->framesize = fh->freeformat_framesize + fh->padding; + } + } + +- switch(fr->lay) ++ switch(fh->lay) + { + #ifndef NO_LAYER1 + case 1: +- fr->spf = 384; +- fr->do_layer = do_layer1; +- if(!fr->freeformat) ++ if(!fh->freeformat) + { +- long fs = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; +- fs /= freqs[fr->sampling_frequency]; +- fs = ((fs+fr->padding)<<2)-4; +- fr->framesize = (int)fs; ++ long fs = (long) tabsel_123[fh->lsf][0][fh->bitrate_index] * 12000; ++ fs /= freqs[fh->sampling_frequency]; ++ fs = ((fs+fh->padding)<<2)-4; ++ fh->framesize = (int)fs; + } + break; + #endif + #ifndef NO_LAYER2 + case 2: +- fr->spf = 1152; +- fr->do_layer = do_layer2; +- if(!fr->freeformat) ++ if(!fh->freeformat) + { +- debug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] ); +- long fs = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; +- fs /= freqs[fr->sampling_frequency]; +- fs += fr->padding - 4; +- fr->framesize = (int)fs; ++ debug2("bitrate index: %i (%i)", fh->bitrate_index, tabsel_123[fh->lsf][1][fh->bitrate_index] ); ++ long fs = (long) tabsel_123[fh->lsf][1][fh->bitrate_index] * 144000; ++ fs /= freqs[fh->sampling_frequency]; ++ fs += fh->padding - 4; ++ fh->framesize = (int)fs; + } + break; + #endif + #ifndef NO_LAYER3 + case 3: +- fr->spf = fr->lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/ +- fr->do_layer = do_layer3; +- if(fr->lsf) +- fr->ssize = (fr->stereo == 1) ? 9 : 17; ++ if(fh->lsf) ++ fh->ssize = (fh->mode == MPG_MD_MONO) ? 9 : 17; + else +- fr->ssize = (fr->stereo == 1) ? 17 : 32; ++ fh->ssize = (fh->mode == MPG_MD_MONO) ? 17 : 32; + +- if(fr->error_protection) +- fr->ssize += 2; ++ if(fh->error_protection) ++ fh->ssize += 2; + +- if(!fr->freeformat) ++ if(!fh->freeformat) + { +- long fs = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; +- fs /= freqs[fr->sampling_frequency]<<(fr->lsf); +- fs += fr->padding - 4; +- fr->framesize = fs; ++ long fs = (long) tabsel_123[fh->lsf][2][fh->bitrate_index] * 144000; ++ fs /= freqs[fh->sampling_frequency]<<(fh->lsf); ++ fs += fh->padding - 4; ++ fh->framesize = fs; + } +- if(fr->framesize < fr->ssize) ++ if(fh->framesize < fh->ssize) + { + if(NOQUIET) + error2( "Frame smaller than mandatory side info (%i < %i)!" +- , fr->framesize, fr->ssize ); ++ , fh->framesize, fh->ssize ); + return PARSE_BAD; + } + break; + #endif + default: +- if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay); ++ if(NOQUIET) error1("Layer type %i not supported in this build!", fh->lay); + + return PARSE_BAD; + } +- if (fr->framesize > MAXFRAMESIZE) ++ if (fh->framesize > MAXFRAMESIZE) + { +- if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding); ++ if(NOQUIET) error1("Frame size too big: %d", fh->framesize+4-fh->padding); + + return PARSE_BAD; + } + return PARSE_GOOD; + } + ++// Apply decoded header structure to frame struct, including ++// main decoder function pointer. ++static void apply_header(mpg123_handle *fr, struct frame_header *hdr) ++{ ++ // copy the whole struct, do some postprocessing ++ fr->hdr = *hdr; ++ fr->stereo = (fr->hdr.mode == MPG_MD_MONO) ? 1 : 2; ++ switch(fr->hdr.lay) ++ { ++#ifndef NO_LAYER1 ++ case 1: ++ fr->spf = 384; ++ fr->do_layer = INT123_do_layer1; ++ break; ++#endif ++#ifndef NO_LAYER2 ++ case 2: ++ fr->spf = 1152; ++ fr->do_layer = INT123_do_layer2; ++ break; ++#endif ++#ifndef NO_LAYER3 ++ case 3: ++ fr->spf = fr->hdr.lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/ ++ fr->do_layer = INT123_do_layer3; ++#endif ++ break; ++ default: ++ // No error checking/message here, been done in decode_header(). ++ fr->spf = 0; ++ fr->do_layer = NULL; ++ } ++} ++ ++ + /* Prepare for bit reading. Two stages: + 0. Layers 1 and 2, side info for layer 3 + 1. Second call for possible bit reservoir for layer 3 part 2,3. +@@ -934,26 +975,26 @@ static int decode_header(mpg123_handle * + void set_pointer(mpg123_handle *fr, int part2, long backstep) + { + fr->bitindex = 0; +- if(fr->lay == 3) ++ if(fr->hdr.lay == 3) + { + if(part2) + { +- fr->wordpointer = fr->bsbuf + fr->ssize - backstep; ++ fr->wordpointer = fr->bsbuf + fr->hdr.ssize - backstep; + if(backstep) + memcpy( fr->wordpointer, fr->bsbufold+fr->fsizeold-backstep + , backstep ); +- fr->bits_avail = (long)(fr->framesize - fr->ssize + backstep)*8; ++ fr->bits_avail = (long)(fr->hdr.framesize - fr->hdr.ssize + backstep)*8; + } + else + { + fr->wordpointer = fr->bsbuf; +- fr->bits_avail = fr->ssize*8; ++ fr->bits_avail = fr->hdr.ssize*8; + } + } + else + { + fr->wordpointer = fr->bsbuf; +- fr->bits_avail = fr->framesize*8; ++ fr->bits_avail = fr->hdr.framesize*8; + } + } + +@@ -961,7 +1002,7 @@ void set_pointer(mpg123_handle *fr, int + + double compute_bpf(mpg123_handle *fr) + { +- return (fr->framesize > 0) ? fr->framesize + 4.0 : 1.0; ++ return (fr->hdr.framesize > 0) ? fr->hdr.framesize + 4.0 : 1.0; + } + + int attribute_align_arg mpg123_spf(mpg123_handle *mh) +@@ -977,8 +1018,8 @@ double attribute_align_arg mpg123_tpf(mp + double tpf; + if(fr == NULL || !fr->firsthead) return MPG123_ERR; + +- tpf = (double) bs[fr->lay]; +- tpf /= freqs[fr->sampling_frequency] << (fr->lsf); ++ tpf = (double) bs[fr->hdr.lay]; ++ tpf /= freqs[fr->hdr.sampling_frequency] << (fr->hdr.lsf); + return tpf; + } + +@@ -1062,7 +1103,7 @@ int get_songlen(mpg123_handle *fr,int no + } + + /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */ +-static int do_readahead(mpg123_handle *fr, unsigned long newhead) ++static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead) + { + unsigned long nexthead = 0; + int hd = 0; +@@ -1074,9 +1115,9 @@ static int do_readahead(mpg123_handle *f + + start = fr->rd->tell(fr); + +- debug2("doing ahead check with BPF %d at %"OFF_P, fr->framesize+4, (off_p)start); ++ debug2("doing ahead check with BPF %d at %"OFF_P, nhdr->framesize+4, (off_p)start); + /* step framesize bytes forward and read next possible header*/ +- if((oret=fr->rd->skip_bytes(fr, fr->framesize))<0) ++ if((oret=fr->rd->skip_bytes(fr, nhdr->framesize))<0) + { + if(oret==READER_ERROR && NOQUIET) error("cannot seek!"); + +@@ -1211,7 +1252,7 @@ static int forget_head_shift(mpg123_hand + } + + /* watch out for junk/tags on beginning of stream by invalid header */ +-static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount) ++static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr) + { + int ret; + int freeformat_count = 0; +@@ -1267,7 +1308,7 @@ static int skip_junk(mpg123_handle *fr, + if(++forgetcount > FORGET_INTERVAL) forgetcount = 0; + if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=0) return ret; + +- if(head_check(newhead) && (ret=decode_header(fr, newhead, &freeformat_count))) break; ++ if(head_check(newhead) && (ret=decode_header(fr, nhdr, newhead, &freeformat_count))) break; + } while(1); + if(ret<0) return ret; + diff -Nru mpg123-1.31.2/debian/patches/series mpg123-1.31.2/debian/patches/series --- mpg123-1.31.2/debian/patches/series 2020-07-05 09:06:10.000000000 +0000 +++ mpg123-1.31.2/debian/patches/series 2024-11-10 15:26:42.000000000 +0000 @@ -1 +1,2 @@ 0001-disable_not_public_funcs.patch +CVE-2024-10573.patch