1From 18490336d91da2b532277cba56473bfed1376fc4 Mon Sep 17 00:00:00 2001 2From: Daniel Axtens <dja@axtens.net> 3Date: Thu, 21 Jan 2021 00:05:58 +1100 4Subject: [PATCH] io/gzio: Add init_dynamic_block() clean up if unpacking codes 5 fails 6 7init_dynamic_block() didn't clean up gzio->tl and td in some error 8paths. This left td pointing to part of tl. Then in grub_gzio_close(), 9when tl was freed the storage for td would also be freed. The code then 10attempts to free td explicitly, performing a UAF and then a double free. 11 12Explicitly clean up tl and td in the error paths. 13 14Signed-off-by: Daniel Axtens <dja@axtens.net> 15Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 16Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 17--- 18 grub-core/io/gzio.c | 12 +++++++++--- 19 1 file changed, 9 insertions(+), 3 deletions(-) 20 21diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c 22index 4a8eaea..4236f0f 100644 23--- a/grub-core/io/gzio.c 24+++ b/grub-core/io/gzio.c 25@@ -953,7 +953,7 @@ init_dynamic_block (grub_gzio_t gzio) 26 if ((unsigned) i + j > n) 27 { 28 grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); 29- return; 30+ goto fail; 31 } 32 while (j--) 33 ll[i++] = l; 34@@ -966,7 +966,7 @@ init_dynamic_block (grub_gzio_t gzio) 35 if ((unsigned) i + j > n) 36 { 37 grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); 38- return; 39+ goto fail; 40 } 41 while (j--) 42 ll[i++] = 0; 43@@ -981,7 +981,7 @@ init_dynamic_block (grub_gzio_t gzio) 44 if ((unsigned) i + j > n) 45 { 46 grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); 47- return; 48+ goto fail; 49 } 50 while (j--) 51 ll[i++] = 0; 52@@ -1019,6 +1019,12 @@ init_dynamic_block (grub_gzio_t gzio) 53 /* indicate we're now working on a block */ 54 gzio->code_state = 0; 55 gzio->block_len++; 56+ return; 57+ 58+ fail: 59+ huft_free (gzio->tl); 60+ gzio->td = NULL; 61+ gzio->tl = NULL; 62 } 63 64 65-- 662.14.2 67 68