libpayload: lzma: Allocate scratchpad on the heap

Allocating a 15980-byte scratchpad on the stack when your default stack
size is set to 16KB is really not a great idea. We're regularly
overflowing into the end of our heap when using LZMA in libpayload, and
just happen not to notice it because the heap rarely gets filled up all
the way. Of course, since we always *have* a heap in libpayload, the
much saner solution is to just use it directly to allocate the
scratchpad rather than accidentally grow backwards into it anyway.

Change-Id: Ibe4f02057a32bd156a126302178fa6fcab637d2c
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/16089
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Julius Werner 2016-08-05 20:43:47 -07:00 committed by Martin Roth
parent 5a6955517f
commit e25d3ff9bd
1 changed files with 7 additions and 3 deletions

View File

@ -10,6 +10,7 @@
*/ */
#include <lzma.h> #include <lzma.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "lzmadecode.c" #include "lzmadecode.c"
@ -25,7 +26,7 @@ unsigned long ulzman(const unsigned char *src, unsigned long srcn,
int res; int res;
CLzmaDecoderState state; CLzmaDecoderState state;
SizeT mallocneeds; SizeT mallocneeds;
unsigned char scratchpad[15980]; unsigned char *scratchpad;
memcpy(properties, src, LZMA_PROPERTIES_SIZE); memcpy(properties, src, LZMA_PROPERTIES_SIZE);
memcpy(&outSize, src + LZMA_PROPERTIES_SIZE, sizeof(outSize)); memcpy(&outSize, src + LZMA_PROPERTIES_SIZE, sizeof(outSize));
@ -37,13 +38,16 @@ unsigned long ulzman(const unsigned char *src, unsigned long srcn,
return 0; return 0;
} }
mallocneeds = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); mallocneeds = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (mallocneeds > 15980) { scratchpad = malloc(mallocneeds);
printf("lzma: Decoder scratchpad too small!\n"); if (!scratchpad) {
printf("lzma: Cannot allocate %u bytes for scratchpad!\n",
mallocneeds);
return 0; return 0;
} }
state.Probs = (CProb *)scratchpad; state.Probs = (CProb *)scratchpad;
res = LzmaDecode(&state, src + data_offset, srcn - data_offset, res = LzmaDecode(&state, src + data_offset, srcn - data_offset,
&inProcessed, dst, outSize, &outProcessed); &inProcessed, dst, outSize, &outProcessed);
free(scratchpad);
if (res != 0) { if (res != 0) {
printf("lzma: Decoding error = %d\n", res); printf("lzma: Decoding error = %d\n", res);
return 0; return 0;