From 608688b3088bb10186700a38b459443d649d6325 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 11 Jul 2022 17:51:19 +0100 Subject: [PATCH] upng-gzip: fuzz: size temp arrays to worst huff size https://oss-fuzz.com/testcase-detail/5964400971874304 The original upng code this is based on just sizes the temp buffers for 15, but the trees can come in 19, 32, or 288 lengths. Set the buffer sizes for the worst case. Add some asserts to help catch any further problems more directly. --- lib/misc/upng-gzip.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/misc/upng-gzip.c b/lib/misc/upng-gzip.c index 722fa3a06..a59998a57 100644 --- a/lib/misc/upng-gzip.c +++ b/lib/misc/upng-gzip.c @@ -242,19 +242,32 @@ huffman_tree_init(htree_t *tree, huff_t *buffer, uint16_t numcodes, static lws_stateful_ret_t huffman_tree_create_lengths(htree_t *tree, const unsigned *bitlen) { - unsigned int tree1d[MAX_SYMBOLS], blcount[MAX_BIT_LENGTH], - nextcode[MAX_BIT_LENGTH + 1]; - unsigned int bits, n, i, nodefilled = 0, treepos = 0; + unsigned int tree1d[NUM_DEFLATE_CODE_SYMBOLS], /* sized to worst */ + blcount[NUM_DEFLATE_CODE_SYMBOLS], /* sized to worst */ + nextcode[MAX_BIT_LENGTH + 1], bits, n, i, + nodefilled = 0, treepos = 0; memset(blcount, 0, sizeof(blcount)); memset(nextcode, 0, sizeof(nextcode)); - for (bits = 0; bits < tree->numcodes; bits++) + assert(tree->numcodes <= LWS_ARRAY_SIZE(blcount)); + + for (bits = 0; bits < tree->numcodes; bits++) { + /* any counts exceeding our private buffer length are fatal */ + if (bitlen[bits] >= LWS_ARRAY_SIZE(blcount)) + return LWS_SRET_FATAL + 1; + blcount[bitlen[bits]]++; + } + + assert(tree->maxbitlen && tree->maxbitlen - 1u <= LWS_ARRAY_SIZE(blcount)); + assert(tree->maxbitlen - 1u <= LWS_ARRAY_SIZE(nextcode)); for (bits = 1; bits <= (unsigned int)tree->maxbitlen; bits++) nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1; + assert(tree->numcodes <= LWS_ARRAY_SIZE(tree1d)); + for (n = 0; n < tree->numcodes; n++) if (bitlen[n]) tree1d[n] = nextcode[bitlen[n]]++;