From 3ceb6e563003fdf159c6838442c420961be76561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Tue, 17 Apr 2018 11:59:46 +0200 Subject: [PATCH] Fix double fclose() with -d while fuzzing * src/ftp.c (ftp_loop_internal): Set warc_tmp to NULL after ffclose() * src/init.c (cleanup): Set output_stream to NULL after fclose() * src/log.c (log_close): Set global stream vars to NULL after closing * src/recur.c (retrieve_tree): Set rejectedlog to NULL after closing * src/warc.c (warc_close): Set stream vars to NULL after closing --- src/ftp.c | 8 +++++++- src/init.c | 7 ++++--- src/log.c | 11 +++++++++-- src/recur.c | 5 ++++- src/warc.c | 8 +++++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/ftp.c b/src/ftp.c index 96527dd8..a0531df0 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -1982,7 +1982,10 @@ ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f, #endif /* Fatal errors, give up. */ if (warc_tmp != NULL) + { fclose (warc_tmp); + warc_tmp = NULL; + } return err; case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR: case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR: @@ -2110,7 +2113,10 @@ Removing file due to --delete-after in ftp_loop_internal():\n")); *local_file = xstrdup (locf); if (warc_tmp != NULL) - fclose (warc_tmp); + { + fclose (warc_tmp); + warc_tmp = NULL; + } return RETROK; } while (!opt.ntry || (count < opt.ntry)); diff --git a/src/init.c b/src/init.c index ac4b2430..d03a20e3 100644 --- a/src/init.c +++ b/src/init.c @@ -1900,11 +1900,12 @@ cleanup (void) log_close (); - if (output_stream) + if (output_stream && output_stream != stderr) { - if (fclose (output_stream) == EOF) - inform_exit_status (CLOSEFAILED); + FILE *fp = output_stream; output_stream = NULL; + if (fclose (fp) == EOF) + inform_exit_status (CLOSEFAILED); } /* No need to check for error because Wget flushes its output (and diff --git a/src/log.c b/src/log.c index 5bff9c23..05b58ceb 100644 --- a/src/log.c +++ b/src/log.c @@ -676,9 +676,16 @@ log_close (void) { int i; - if (logfp && (logfp != stderr)) - fclose (logfp); + if (logfp && logfp != stderr && logfp != stdout) + { + if (logfp == stdlogfp) + stdlogfp = NULL; + if (logfp == filelogfp) + filelogfp = NULL; + fclose (logfp); + } logfp = NULL; + inhibit_logging = true; save_context_p = false; diff --git a/src/recur.c b/src/recur.c index 1957f003..0a173dde 100644 --- a/src/recur.c +++ b/src/recur.c @@ -524,7 +524,10 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi) } if (rejectedlog) - fclose (rejectedlog); + { + fclose (rejectedlog); + rejectedlog = NULL; + } /* If anything is left of the queue due to a premature exit, free it now. */ diff --git a/src/warc.c b/src/warc.c index 9cbbca39..3482cf3b 100644 --- a/src/warc.c +++ b/src/warc.c @@ -1240,9 +1240,15 @@ warc_close (void) warc_write_metadata (); *warc_current_warcinfo_uuid_str = 0; fclose (warc_current_file); + warc_current_file = NULL; } + if (warc_current_cdx_file != NULL) - fclose (warc_current_cdx_file); + { + fclose (warc_current_cdx_file); + warc_current_cdx_file = NULL; + } + if (warc_log_fp != NULL) { fclose (warc_log_fp);