From: Wouter Wijngaards Date: Fri, 4 Jul 2014 07:34:58 +0000 (+0000) Subject: - Fix #593: segfault or crash upon rotating logfile. X-Git-Tag: release-1.5.0rc1~104 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5bf2cf802411e112f0ade9854dc650cfd81c96b;p=thirdparty%2Funbound.git - Fix #593: segfault or crash upon rotating logfile. git-svn-id: file:///svn/unbound/trunk@3156 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 80efcb1a8..8ea4dc554 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +4 July 2014: Wouter + - Fix #593: segfault or crash upon rotating logfile. + 3 July 2014: Wouter - DLV tests added. - signit tool fixup for compile with libldns library. diff --git a/util/log.c b/util/log.c index 39d3118a0..a3bffbf38 100644 --- a/util/log.c +++ b/util/log.c @@ -68,6 +68,8 @@ static FILE* logfile = 0; static int key_created = 0; /** pthread key for thread ids in logfile */ static ub_thread_key_t logkey; +/** pthread mutex to protect FILE* */ +static lock_quick_t log_lock; /** the identity of this executable/process */ static const char* ident="unbound"; #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) @@ -86,14 +88,19 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) if(!key_created) { key_created = 1; ub_thread_key_create(&logkey, NULL); + lock_quick_init(&log_lock); } + lock_quick_lock(&log_lock); if(logfile #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) || logging_to_syslog #endif - ) - verbose(VERB_QUERY, "switching log to %s", - use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); + ) { + lock_quick_unlock(&log_lock); /* verbose() needs the lock */ + verbose(VERB_QUERY, "switching log to %s", + use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); + lock_quick_lock(&log_lock); + } if(logfile && logfile != stderr) fclose(logfile); #ifdef HAVE_SYSLOG_H @@ -106,6 +113,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) * chroot and no longer be able to access dev/log and so on */ openlog(ident, LOG_NDELAY, LOG_DAEMON); logging_to_syslog = 1; + lock_quick_unlock(&log_lock); return; } #elif defined(UB_ON_WINDOWS) @@ -114,11 +122,13 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) } if(use_syslog) { logging_to_syslog = 1; + lock_quick_unlock(&log_lock); return; } #endif /* HAVE_SYSLOG_H */ if(!filename || !filename[0]) { logfile = stderr; + lock_quick_unlock(&log_lock); return; } /* open the file for logging */ @@ -127,6 +137,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) filename += strlen(chrootdir); f = fopen(filename, "a"); if(!f) { + lock_quick_unlock(&log_lock); log_err("Could not open logfile %s: %s", filename, strerror(errno)); return; @@ -136,11 +147,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) setvbuf(f, NULL, (int)_IOLBF, 0); #endif logfile = f; + lock_quick_unlock(&log_lock); } void log_file(FILE *f) { + lock_quick_lock(&log_lock); logfile = f; + lock_quick_unlock(&log_lock); } void log_thread_set(int* num) @@ -211,7 +225,11 @@ log_vmsg(int pri, const char* type, return; } #endif /* HAVE_SYSLOG_H */ - if(!logfile) return; + lock_quick_lock(&log_lock); + if(!logfile) { + lock_quick_unlock(&log_lock); + return; + } if(log_now) now = (time_t)*log_now; else now = (time_t)time(NULL); @@ -236,6 +254,7 @@ log_vmsg(int pri, const char* type, /* line buffering does not work on windows */ fflush(logfile); #endif + lock_quick_unlock(&log_lock); } /**