From b6d05666421dff17f5bb91b2ec17d8ec2cace03d Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Wed, 20 Oct 2021 00:27:14 -0400 Subject: [PATCH] Plug memory leaks identified by fuzzer+Valgrind --- crates/engine_xetex/xetex/xetex-ext.c | 2 ++ crates/engine_xetex/xetex/xetex-ini.c | 14 +++++++++++++- crates/pdf_io/pdf_io/dpx-pdfdraw.c | 12 +++++++++++- fuzz/run-fuzzer.sh | 7 +++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/crates/engine_xetex/xetex/xetex-ext.c b/crates/engine_xetex/xetex/xetex-ext.c index 93f03932..71dbbba8 100644 --- a/crates/engine_xetex/xetex/xetex-ext.c +++ b/crates/engine_xetex/xetex/xetex-ext.c @@ -218,6 +218,8 @@ load_mapping_file(const char* s, const char* e, char byteMapping) font_mapping_warning(buffer, strlen(buffer), 2); /* not loadable */ else if (get_tracing_fonts_state() > 1) font_mapping_warning(buffer, strlen(buffer), 0); /* tracing */ + + free(mapping); } else { font_mapping_warning(buffer, strlen(buffer), 1); /* not found */ } diff --git a/crates/engine_xetex/xetex/xetex-ini.c b/crates/engine_xetex/xetex/xetex-ini.c index 6dffc50f..2f335e2d 100644 --- a/crates/engine_xetex/xetex/xetex-ini.c +++ b/crates/engine_xetex/xetex/xetex-ini.c @@ -3,6 +3,13 @@ Licensed under the MIT License. */ +/* On Windows this can bring in a `#define INPUT` that clashes with + * xetex_format.h, so include it first and sanitize: */ +#include "teckit-c-Engine.h" +#ifdef INPUT +#undef INPUT +#endif + #include "xetex-core.h" #include "xetex-xetexd.h" #include "xetex-synctex.h" @@ -2764,7 +2771,7 @@ load_fmt_file(void) font_ptr = x; - font_mapping = xmalloc_array(void *, font_max); + font_mapping = xcalloc_array(void *, font_max); font_layout_engine = xcalloc_array(void *, font_max); font_flags = xmalloc_array(char, font_max); font_letter_space = xmalloc_array(scaled_t, font_max); @@ -3508,6 +3515,11 @@ tt_cleanup(void) { release_font_engine(font_layout_engine[font_k], font_area[font_k]); font_layout_engine[font_k] = NULL; } + + if (font_mapping[font_k] != NULL) { + TECkit_DisposeConverter((TECkit_Converter) font_mapping[font_k]); + font_mapping[font_k] = NULL; + } } for (int i = 1; i <= in_open; i++) { diff --git a/crates/pdf_io/pdf_io/dpx-pdfdraw.c b/crates/pdf_io/pdf_io/dpx-pdfdraw.c index 1f4faa92..9fbb1f8d 100644 --- a/crates/pdf_io/pdf_io/dpx-pdfdraw.c +++ b/crates/pdf_io/pdf_io/dpx-pdfdraw.c @@ -878,7 +878,7 @@ typedef struct pdf_gstate_ pdf_obj *extgstate; } pdf_gstate; -static dpx_stack gs_stack; +static dpx_stack gs_stack = { 0, NULL, NULL }; static void init_a_gstate (pdf_gstate *gs) @@ -1112,6 +1112,16 @@ pdf_dev_init_gstates (void) { pdf_gstate *gs; + /* Tectonic: this function is called twice in the xdvipdfmx driver init, + * resulting in a small amount of leaked memory. We statically initialize the + * stack variable to make it possible to safely avoid the leak in this + * situation. */ + + while ((gs = dpx_stack_pop(&gs_stack)) != NULL) { + clear_a_gstate(gs); + free(gs); + } + dpx_stack_init(&gs_stack); gs = NEW(1, pdf_gstate); diff --git a/fuzz/run-fuzzer.sh b/fuzz/run-fuzzer.sh index 6d1c0bf4..70b7f961 100755 --- a/fuzz/run-fuzzer.sh +++ b/fuzz/run-fuzzer.sh @@ -1,4 +1,11 @@ #!/usr/bin/env bash + +# NOTE: install `llvm-dev` or whichever package provides `llvm-symbolizer` if +# you want your stack traces to have any useful information! Otherwise none of +# the binary addresses are decoded when the fuzzer finds problems. You may also +# need to add the `-D` flag to `cargo fuzz run` to get more meaningful +# backtraces, at the expense of the fuzzer running much slower. + set -e set -o pipefail HERE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"