|
33 | 33 | // Timur Gagiev |
34 | 34 | // |
35 | 35 | // Partial history: |
| 36 | +// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure) |
36 | 37 | // 1.16 - 2019-03-04 - fix warnings |
37 | 38 | // 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found |
38 | 39 | // 1.14 - 2018-02-11 - delete bogus dealloca usage |
@@ -1202,8 +1203,10 @@ static int lookup1_values(int entries, int dim) |
1202 | 1203 | int r = (int) floor(exp((float) log((float) entries) / dim)); |
1203 | 1204 | if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; |
1204 | 1205 | ++r; // floor() to avoid _ftol() when non-CRT |
1205 | | - assert(pow((float) r+1, dim) > entries); |
1206 | | - assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above |
| 1206 | + if (pow((float) r+1, dim) <= entries) |
| 1207 | + return -1; |
| 1208 | + if ((int) floor(pow((float) r, dim)) > entries) |
| 1209 | + return -1; |
1207 | 1210 | return r; |
1208 | 1211 | } |
1209 | 1212 |
|
@@ -2013,15 +2016,15 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y |
2013 | 2016 | ady -= abs(base) * adx; |
2014 | 2017 | if (x1 > n) x1 = n; |
2015 | 2018 | if (x < x1) { |
2016 | | - LINE_OP(output[x], inverse_db_table[y]); |
| 2019 | + LINE_OP(output[x], inverse_db_table[y&255]); |
2017 | 2020 | for (++x; x < x1; ++x) { |
2018 | 2021 | err += ady; |
2019 | 2022 | if (err >= adx) { |
2020 | 2023 | err -= adx; |
2021 | 2024 | y += sy; |
2022 | 2025 | } else |
2023 | 2026 | y += base; |
2024 | | - LINE_OP(output[x], inverse_db_table[y]); |
| 2027 | + LINE_OP(output[x], inverse_db_table[y&255]); |
2025 | 2028 | } |
2026 | 2029 | } |
2027 | 2030 | } |
@@ -3048,7 +3051,6 @@ static float *get_window(vorb *f, int len) |
3048 | 3051 | len <<= 1; |
3049 | 3052 | if (len == f->blocksize_0) return f->window[0]; |
3050 | 3053 | if (len == f->blocksize_1) return f->window[1]; |
3051 | | - assert(0); |
3052 | 3054 | return NULL; |
3053 | 3055 | } |
3054 | 3056 |
|
@@ -3454,6 +3456,7 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) |
3454 | 3456 | if (f->previous_length) { |
3455 | 3457 | int i,j, n = f->previous_length; |
3456 | 3458 | float *w = get_window(f, n); |
| 3459 | + if (w == NULL) return 0; |
3457 | 3460 | for (i=0; i < f->channels; ++i) { |
3458 | 3461 | for (j=0; j < n; ++j) |
3459 | 3462 | f->channel_buffers[i][left+j] = |
@@ -3695,6 +3698,7 @@ static int start_decoder(vorb *f) |
3695 | 3698 | while (current_entry < c->entries) { |
3696 | 3699 | int limit = c->entries - current_entry; |
3697 | 3700 | int n = get_bits(f, ilog(limit)); |
| 3701 | + if (current_length >= 32) return error(f, VORBIS_invalid_setup); |
3698 | 3702 | if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } |
3699 | 3703 | memset(lengths + current_entry, current_length, n); |
3700 | 3704 | current_entry += n; |
@@ -3798,7 +3802,9 @@ static int start_decoder(vorb *f) |
3798 | 3802 | c->value_bits = get_bits(f, 4)+1; |
3799 | 3803 | c->sequence_p = get_bits(f,1); |
3800 | 3804 | if (c->lookup_type == 1) { |
3801 | | - c->lookup_values = lookup1_values(c->entries, c->dimensions); |
| 3805 | + int values = lookup1_values(c->entries, c->dimensions); |
| 3806 | + if (values < 0) return error(f, VORBIS_invalid_setup); |
| 3807 | + c->lookup_values = (uint32) values; |
3802 | 3808 | } else { |
3803 | 3809 | c->lookup_values = c->entries * c->dimensions; |
3804 | 3810 | } |
@@ -3934,6 +3940,9 @@ static int start_decoder(vorb *f) |
3934 | 3940 | p[j].id = j; |
3935 | 3941 | } |
3936 | 3942 | qsort(p, g->values, sizeof(p[0]), point_compare); |
| 3943 | + for (j=0; j < g->values-1; ++j) |
| 3944 | + if (p[j].x == p[j+1].x) |
| 3945 | + return error(f, VORBIS_invalid_setup); |
3937 | 3946 | for (j=0; j < g->values; ++j) |
3938 | 3947 | g->sorted_order[j] = (uint8) p[j].id; |
3939 | 3948 | // precompute the neighbors |
@@ -4020,6 +4029,7 @@ static int start_decoder(vorb *f) |
4020 | 4029 | max_submaps = m->submaps; |
4021 | 4030 | if (get_bits(f,1)) { |
4022 | 4031 | m->coupling_steps = get_bits(f,8)+1; |
| 4032 | + if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup); |
4023 | 4033 | for (k=0; k < m->coupling_steps; ++k) { |
4024 | 4034 | m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); |
4025 | 4035 | m->chan[k].angle = get_bits(f, ilog(f->channels-1)); |
@@ -5386,6 +5396,12 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in |
5386 | 5396 | #endif // STB_VORBIS_NO_PULLDATA_API |
5387 | 5397 |
|
5388 | 5398 | /* Version history |
| 5399 | + 1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13223, -13223 |
| 5400 | + found with Mayhem by ForAllSecure |
| 5401 | + 1.16 - 2019-03-04 - fix warnings |
| 5402 | + 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found |
| 5403 | + 1.14 - 2018-02-11 - delete bogus dealloca usage |
| 5404 | + 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) |
5389 | 5405 | 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files |
5390 | 5406 | 1.11 - 2017-07-23 - fix MinGW compilation |
5391 | 5407 | 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory |
|
0 commit comments