Skip to content

Commit a214a46

Browse files
author
Timothy B. Terriberry
committed
Fix overflow and OOB read for large ext lengths.
With an 8+ MB packet it is possible to craft an extension length that would overflow, bypassing the checks to ensure the extension data remains inside the packet. This patch fixes that and adds a test for it.
1 parent fc96bb9 commit a214a46

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

src/extensions.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,23 @@ opus_int32 skip_extension(const unsigned char **data, opus_int32 len, opus_int32
6969
return 0;
7070
} else {
7171
opus_int32 bytes=0;
72+
opus_int32 lacing;
7273
*header_size = 1;
7374
do {
7475
(*data)++;
7576
len--;
76-
if (len == 0)
77+
if (len < 1)
7778
return -1;
78-
bytes += **data;
79+
lacing = **data;
80+
bytes += lacing;
7981
(*header_size)++;
80-
} while (**data == 255);
82+
len -= lacing;
83+
} while (lacing == 255);
84+
if (len < 1)
85+
return -1;
8186
(*data)++;
8287
len--;
83-
if (bytes <= len)
84-
{
85-
len -= bytes;
86-
*data += bytes;
87-
} else {
88-
return -1;
89-
}
88+
*data += bytes;
9089
return len;
9190
}
9291
}

tests/test_opus_extensions.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,20 @@ void test_extensions_parse_fail(void)
303303
len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
304304
result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
305305
expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
306+
307+
/* overflow for long extension length */
308+
{
309+
/* about 8 MB */
310+
#define LENSIZE ((1U<<31)/255 + 1)
311+
unsigned char *buf = malloc(LENSIZE+1);
312+
len = LENSIZE+1;
313+
buf[0] = 33<<1 | 1;
314+
memset(buf + 1, 0xFF, LENSIZE - 1);
315+
buf[LENSIZE] = 0xFE;
316+
result = opus_packet_extensions_parse(buf, len, ext_out, &nb_ext);
317+
expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
318+
free(buf);
319+
}
306320
}
307321

308322
#define NB_RANDOM_EXTENSIONS 100000000

0 commit comments

Comments
 (0)