Skip to content

Commit

Permalink
au: avoid int overflow while calculating data_end
Browse files Browse the repository at this point in the history
At several points in au_read_header(), we calculate the functional end
of the data segment by adding the (int)au_fmt.dataoffset and the
(int)au_fmt.datasize. This can overflow the implicit int_32 return value
and cause undefined behavior.

Instead, precalculate the value and assign it to a 64-bit
(sf_count_t)data_end variable.

CVE: CVE-2022-33065
Fixes: libsndfile#833

Signed-off-by: Alex Stewart <alex.stewart@ni.com>
  • Loading branch information
amstewart authored and jpautler committed Nov 29, 2023
1 parent 7bf4881 commit 65f84b4
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/au.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ static int
au_read_header (SF_PRIVATE *psf)
{ AU_FMT au_fmt ;
int marker, dword ;
sf_count_t data_end ;

memset (&au_fmt, 0, sizeof (au_fmt)) ;
psf_binheader_readf (psf, "pm", 0, &marker) ;
Expand All @@ -317,14 +318,15 @@ au_read_header (SF_PRIVATE *psf)
return SFE_AU_EMBED_BAD_LEN ;
} ;

data_end = (sf_count_t) au_fmt.dataoffset + (sf_count_t) au_fmt.datasize ;
if (psf->fileoffset > 0)
{ psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
{ psf->filelength = data_end ;
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
}
else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength)
else if (au_fmt.datasize == -1 || data_end == psf->filelength)
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength)
{ psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
else if (data_end < psf->filelength)
{ psf->filelength = data_end ;
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
}
else
Expand Down

0 comments on commit 65f84b4

Please sign in to comment.