summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2013-08-16 07:59:15 -0700
committerSimon Glass <sjg@chromium.org>2013-09-03 13:30:23 -0600
commitff9d2efdbf1b3b5263f81e843c6724b8bead7f1f (patch)
tree29d4f744ce001d3d3602da6077d1cc0f42353422 /lib
parentafca294289949b118a192b77be947379734ea620 (diff)
lzo: correctly bounds-check output buffer
This checks the size of the output buffer and fails if it was going to overflow the buffer during lzo decompression. Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/lzo/lzo1x_decompress.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c
index e6ff708f119..35f3793f31c 100644
--- a/lib/lzo/lzo1x_decompress.c
+++ b/lib/lzo/lzo1x_decompress.c
@@ -68,13 +68,14 @@ int lzop_decompress(const unsigned char *src, size_t src_len,
unsigned char *start = dst;
const unsigned char *send = src + src_len;
u32 slen, dlen;
- size_t tmp;
+ size_t tmp, remaining;
int r;
src = parse_header(src);
if (!src)
return LZO_E_ERROR;
+ remaining = *dst_len;
while (src < send) {
/* read uncompressed block size */
dlen = get_unaligned_be32(src);
@@ -93,6 +94,10 @@ int lzop_decompress(const unsigned char *src, size_t src_len,
if (slen <= 0 || slen > dlen)
return LZO_E_ERROR;
+ /* abort if buffer ran out of room */
+ if (dlen > remaining)
+ return LZO_E_OUTPUT_OVERRUN;
+
/* decompress */
tmp = dlen;
r = lzo1x_decompress_safe((u8 *) src, slen, dst, &tmp);
@@ -105,6 +110,7 @@ int lzop_decompress(const unsigned char *src, size_t src_len,
src += slen;
dst += dlen;
+ remaining -= dlen;
}
return LZO_E_INPUT_OVERRUN;