From 9f21c81633504696fc68a8ca94465460c54c5243 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 12 Apr 2013 17:25:51 +0200 Subject: demux_mkv: use a bounded buffer for block data Should help avoiding out-of-bounds reads. --- demux/ebml.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'demux/ebml.c') diff --git a/demux/ebml.c b/demux/ebml.c index 9dbc2c22f7..52332cd0c5 100644 --- a/demux/ebml.c +++ b/demux/ebml.c @@ -64,44 +64,49 @@ uint32_t ebml_read_id(stream_t *s, int *length) /* * Read a variable length unsigned int. */ -uint64_t ebml_read_vlen_uint(uint8_t *buffer, int *length) +uint64_t ebml_read_vlen_uint(bstr *buffer) { int i, j, num_ffs = 0, len_mask = 0x80; uint64_t num; - for (i = 0, num = *buffer++; i < 8 && !(num & len_mask); i++) + if (buffer->len == 0) + return EBML_UINT_INVALID; + + for (i = 0, num = buffer->start[0]; i < 8 && !(num & len_mask); i++) len_mask >>= 1; if (i >= 8) return EBML_UINT_INVALID; j = i + 1; - if (length) - *length = j; if ((int) (num &= (len_mask - 1)) == len_mask - 1) num_ffs++; - while (i--) { - num = (num << 8) | *buffer++; + if (j > buffer->len) + return EBML_UINT_INVALID; + for (int n = 0; n < i; n++) { + num = (num << 8) | buffer->start[n + 1]; if ((num & 0xFF) == 0xFF) num_ffs++; } if (j == num_ffs) return EBML_UINT_INVALID; + buffer->start += j; + buffer->len -= j; return num; } /* * Read a variable length signed int. */ -int64_t ebml_read_vlen_int(uint8_t *buffer, int *length) +int64_t ebml_read_vlen_int(bstr *buffer) { uint64_t unum; int l; /* read as unsigned number first */ - unum = ebml_read_vlen_uint(buffer, &l); + size_t len = buffer->len; + unum = ebml_read_vlen_uint(buffer); if (unum == EBML_UINT_INVALID) return EBML_INT_INVALID; - if (length) - *length = l; + l = len - buffer->len; return unum - ((1 << ((7 * l) - 1)) - 1); } -- cgit v1.2.3