Commit 2c9a5172 authored by Reimar Döffinger's avatar Reimar Döffinger Committed by Anton Khirnov

dfa: fix buffer overflow checks to avoid integer overflows.

Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent 7e19a6e8
...@@ -62,12 +62,14 @@ static int decode_tsw1(uint8_t *frame, int width, int height, ...@@ -62,12 +62,14 @@ static int decode_tsw1(uint8_t *frame, int width, int height,
const uint8_t *frame_start = frame; const uint8_t *frame_start = frame;
const uint8_t *frame_end = frame + width * height; const uint8_t *frame_end = frame + width * height;
int mask = 0x10000, bitbuf = 0; int mask = 0x10000, bitbuf = 0;
int v, offset, count, segments; int v, count, segments;
unsigned offset;
segments = bytestream_get_le32(&src); segments = bytestream_get_le32(&src);
frame += bytestream_get_le32(&src); offset = bytestream_get_le32(&src);
if (frame < frame_start || frame > frame_end) if (frame_end - frame <= offset)
return -1; return -1;
frame += offset;
while (segments--) { while (segments--) {
if (mask == 0x10000) { if (mask == 0x10000) {
if (src >= src_end) if (src >= src_end)
...@@ -189,11 +191,11 @@ static int decode_bdlt(uint8_t *frame, int width, int height, ...@@ -189,11 +191,11 @@ static int decode_bdlt(uint8_t *frame, int width, int height,
int count, lines, segments; int count, lines, segments;
count = bytestream_get_le16(&src); count = bytestream_get_le16(&src);
if (count >= height || width * count < 0) if (count >= height)
return -1; return -1;
frame += width * count; frame += width * count;
lines = bytestream_get_le16(&src); lines = bytestream_get_le16(&src);
if (frame + lines * width > frame_end || src >= src_end) if (count + lines > height || src >= src_end)
return -1; return -1;
while (lines--) { while (lines--) {
...@@ -203,17 +205,17 @@ static int decode_bdlt(uint8_t *frame, int width, int height, ...@@ -203,17 +205,17 @@ static int decode_bdlt(uint8_t *frame, int width, int height,
while (segments--) { while (segments--) {
if (src_end - src < 3) if (src_end - src < 3)
return -1; return -1;
line_ptr += *src++; if (frame - line_ptr <= *src)
if (line_ptr >= frame)
return -1; return -1;
line_ptr += *src++;
count = (int8_t)*src++; count = (int8_t)*src++;
if (count >= 0) { if (count >= 0) {
if (line_ptr + count > frame || src_end - src < count) if (frame - line_ptr < count || src_end - src < count)
return -1; return -1;
bytestream_get_buffer(&src, line_ptr, count); bytestream_get_buffer(&src, line_ptr, count);
} else { } else {
count = -count; count = -count;
if (line_ptr + count > frame || src >= src_end) if (frame - line_ptr < count || src >= src_end)
return -1; return -1;
memset(line_ptr, *src++, count); memset(line_ptr, *src++, count);
} }
...@@ -232,15 +234,16 @@ static int decode_wdlt(uint8_t *frame, int width, int height, ...@@ -232,15 +234,16 @@ static int decode_wdlt(uint8_t *frame, int width, int height,
int count, i, v, lines, segments; int count, i, v, lines, segments;
lines = bytestream_get_le16(&src); lines = bytestream_get_le16(&src);
if (frame + lines * width > frame_end || src >= src_end) if (lines > height || src >= src_end)
return -1; return -1;
while (lines--) { while (lines--) {
segments = bytestream_get_le16(&src); segments = bytestream_get_le16(&src);
while ((segments & 0xC000) == 0xC000) { while ((segments & 0xC000) == 0xC000) {
frame -= (int16_t)segments * width; unsigned delta = -((int16_t)segments * width);
if (frame >= frame_end) if (frame_end - frame <= delta)
return -1; return -1;
frame += delta;
segments = bytestream_get_le16(&src); segments = bytestream_get_le16(&src);
} }
if (segments & 0x8000) { if (segments & 0x8000) {
...@@ -252,18 +255,18 @@ static int decode_wdlt(uint8_t *frame, int width, int height, ...@@ -252,18 +255,18 @@ static int decode_wdlt(uint8_t *frame, int width, int height,
while (segments--) { while (segments--) {
if (src_end - src < 2) if (src_end - src < 2)
return -1; return -1;
line_ptr += *src++; if (frame - line_ptr <= *src)
if (line_ptr >= frame)
return -1; return -1;
line_ptr += *src++;
count = (int8_t)*src++; count = (int8_t)*src++;
if (count >= 0) { if (count >= 0) {
if (line_ptr + count*2 > frame || src_end - src < count*2) if (frame - line_ptr < count*2 || src_end - src < count*2)
return -1; return -1;
bytestream_get_buffer(&src, line_ptr, count*2); bytestream_get_buffer(&src, line_ptr, count*2);
line_ptr += count * 2; line_ptr += count * 2;
} else { } else {
count = -count; count = -count;
if (line_ptr + count*2 > frame || src_end - src < 2) if (frame - line_ptr < count*2 || src_end - src < 2)
return -1; return -1;
v = bytestream_get_le16(&src); v = bytestream_get_le16(&src);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment