ref: 4cf97afb0123a5915bdfba7c843bc2185c8e2fa6
parent: 19b81b0cb9c82430a01c4806543a580d3b656dd0
parent: 6823e6610c9af1b0080cb22b9da03efb208d7d57
author: Fabian Greffrath <fabian@greffrath.com>
date: Mon Aug 26 10:20:28 EDT 2019
Merge pull request #38 from hlef/master specrec: better handle unexpected PS (CVE-2018-20360/CVE-2018-20199)
--- a/libfaad/ps_dec.c
+++ b/libfaad/ps_dec.c
@@ -1508,6 +1508,20 @@
//printf("%d\n", ps->iid_index[env][bk]);
+ /* index range is supposed to be -7...7 or -15...15 depending on iid_mode
+ (Table 8.24, ISO/IEC 14496-3:2005).
+ if it is outside these boundaries, this is most likely an error. sanitize
+ it and try to process further. */
+ if (ps->iid_index[env][bk] < -no_iid_steps) {
+ fprintf(stderr, "Warning: invalid iid_index: %d < %d\n", ps->iid_index[env][bk],
+ -no_iid_steps);
+ ps->iid_index[env][bk] = -no_iid_steps;
+ } else if (ps->iid_index[env][bk] > no_iid_steps) {
+ fprintf(stderr, "Warning: invalid iid_index: %d > %d\n", ps->iid_index[env][bk],
+ no_iid_steps);
+ ps->iid_index[env][bk] = no_iid_steps;
+ }
+
/* calculate the scalefactors c_1 and c_2 from the intensity differences */
c_1 = sf_iid[no_iid_steps + ps->iid_index[env][bk]];
c_2 = sf_iid[no_iid_steps - ps->iid_index[env][bk]];
--- a/libfaad/specrec.c
+++ b/libfaad/specrec.c
@@ -915,18 +915,18 @@
/* element_output_channels not set yet */
hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
} else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != output_channels) {
- /* element inconsistency */
-
- /* this only happens if PS is actually found but not in the first frame
+ /* element inconsistency
+ * this only happens if PS is actually found but not in the first frame
* this means that there is only 1 bitstream element!
*/
- /* reset the allocation */
- hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0;
-
- hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
-
- //return 21;
+ if (hDecoder->fr_channels == 1) {
+ /* reset the allocation */
+ hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0;
+ hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+ } else {
+ return 21;
+ }
}
if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)