init_dynamic_block() didn't clean up gzio->tl and td in some error
paths. This left td pointing to part of tl. Then in grub_gzio_close(),
when tl was freed the storage for td would also be freed. The code then
attempts to free td explicitly, performing a UAF and then a double free.
Explicitly clean up tl and td in the error paths.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = l;
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = 0;
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = 0;
/* indicate we're now working on a block */
gzio->code_state = 0;
gzio->block_len++;
+ return;
+
+ fail:
+ huft_free (gzio->tl);
+ gzio->td = NULL;
+ gzio->tl = NULL;
}