From 89b00ed4f06c4da94f082ad9ced7587679cfd662 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Wed, 13 Feb 2008 22:15:59 +0000 Subject: [PATCH] This patch adds dst_len for the lar uncompress functions, enabling buffer overflow checks. It exits with an error instead of overflowing. Signed-off-by: Myles Watson Acked-by: Ronald G. Minnich git-svn-id: svn://coreboot.org/repository/coreboot-v3@594 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- util/lar/lar.h | 10 +++++----- util/lar/lib.c | 13 ++++++++++--- util/lar/stream.c | 1 + util/lzma/minilzma.cc | 16 +++++++++++----- util/nrv2b/nrv2b.c | 6 +++--- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/util/lar/lar.h b/util/lar/lar.h index c2b42b9c06..42c9a2c271 100644 --- a/util/lar/lar.h +++ b/util/lar/lar.h @@ -94,17 +94,17 @@ struct lar { enum compalgo { none = 0, lzma = 1, nrv2b = 2 }; typedef void (*compress_func) (char *, int, char *, int *); -typedef void (*uncompress_func) (char *, char *, int); +typedef void (*uncompress_func) (char *, int, char *, int); void compress_impossible(char *in, int in_len, char *out, int *out_len); void do_no_compress(char *in, int in_len, char *out, int *out_len); void do_lzma_compress(char *in, int in_len, char *out, int *out_len); void do_nrv2b_compress(char *in, int in_len, char *out, int *out_len); -void uncompress_impossible(char *, char *, int); -void do_no_uncompress(char *, char *, int); -void do_lzma_uncompress(char *, char *, int); -void do_nrv2b_uncompress(char *, char *, int); +void uncompress_impossible(char *dst, int dst_len, char *src, int src_len); +void do_no_uncompress(char *dst, int dst_len, char *src, int src_len); +void do_lzma_uncompress(char *dst, int dst_len, char *src, int src_len); +void do_nrv2b_uncompress(char *dst, int dst_len, char *src, int src_len); static compress_func compress_functions[] = { do_no_compress, diff --git a/util/lar/lib.c b/util/lar/lib.c index 848d0aeca7..d9388c64f6 100644 --- a/util/lar/lib.c +++ b/util/lar/lib.c @@ -60,15 +60,22 @@ void do_no_compress(char *in, int in_len, char *out, int *out_len) * The default "uncompress" hook to call when no other compression is used */ -void do_no_uncompress(char *dst, char *src, int len) +void do_no_uncompress(char *dst, int dst_len, char *src, int src_len) { - memcpy(dst, src, len); + if (dst_len == src_len) + memcpy(dst, src, dst_len); + else + { + fprintf(stderr,"%s: src_len(%d)!=dst_len(%d)\n", + __FUNCTION__,src_len,dst_len); + exit(1); + } } /** * The default "uncompress" hook to call when no other compression is used */ -void uncompress_impossible(char *dst, char *src, int len) +void uncompress_impossible(char *dst, int dst_len, char *src, int src_len) { fprintf(stderr, "Cannot uncompress data (algorithm not compiled in).\n"); diff --git a/util/lar/stream.c b/util/lar/stream.c index 74608144e8..5439b23df3 100644 --- a/util/lar/stream.c +++ b/util/lar/stream.c @@ -685,6 +685,7 @@ int lar_extract_files(struct lar *lar, struct file *files) uncompress_functions[ntohl(header->compression)]( (char*) buf, + ntohl(header->reallen), (char *) ptr + ntohl(header->offset), ntohl(header->len)); diff --git a/util/lzma/minilzma.cc b/util/lzma/minilzma.cc index 90a233a3ac..ffa2016fd6 100644 --- a/util/lzma/minilzma.cc +++ b/util/lzma/minilzma.cc @@ -280,18 +280,24 @@ int main(int argc, char *argv[]) #else extern "C" { -void do_lzma_compress(char *in, int in_len, char *out, - int *out_len) { +void do_lzma_compress(char *in, int in_len, char *out, int *out_len) { std::vector result; result = LZMACompress(std::vector(in, in + in_len)); *out_len = result.size(); std::memcpy(out, &result[0], *out_len); } -void do_lzma_uncompress(char *dst, char *src, int len) { +void do_lzma_uncompress(char *dst, int dst_len, char *src, int src_len) { std::vector result; - result = LZMADeCompress(std::vector(src, src + len)); - std::memcpy(dst, &result[0], result.size()); + result = LZMADeCompress(std::vector(src, src + src_len)); + if (result.size() <= dst_len) + std::memcpy(dst, &result[0], result.size()); + else + { + fprintf(stderr, "Not copying %d bytes to %d-byte buffer!\n", + result.size(), dst_len); + exit(1); + } } } diff --git a/util/nrv2b/nrv2b.c b/util/nrv2b/nrv2b.c index 6f6fe62bf9..52ef0d138c 100644 --- a/util/nrv2b/nrv2b.c +++ b/util/nrv2b/nrv2b.c @@ -1338,16 +1338,16 @@ void do_nrv2b_compress(uint8_t *in, int in_len, uint8_t *out, int *out_len) { #error "Bad Combination of ENDIAN and BITSIZE values specified" #endif -#undef SAFE +#define SAFE #ifdef SAFE -#define FAIL(x,r) if (x) { Error(r); } +#define FAIL(x,r) if (x) { fprintf(stderr,r); exit(1); } #else #define FAIL(x,r) #endif #ifdef COMPACT -void do_nrv2b_uncompress(uint8_t *dst, uint8_t *src, int len) { +void do_nrv2b_uncompress(uint8_t *dst, int dst_len, uint8_t *src, int src_len) { unsigned long ilen = 0, olen = 0, last_m_off = 1; uint32_t bb = 0; unsigned bc = 0;