diff --git a/CHANGES b/CHANGES index 5dfbc05..c3cabd2 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,12 @@ corrections: may result in partial writes and/or EAGAIN errors that were not handled properly but resulted in data loss or process termination. + Fixed a bug that could freeze socat when during assembly of a log + message a signal was handled that also printed a log message. socat + development had been aware that localtime() is not thread safe but had + only expected broken messages, not corrupted stack (glibc 2.11.1, + Ubuntu 10.4) + ####################### V 1.7.1.3: security: diff --git a/error.c b/error.c index 551788f..b1ee304 100644 --- a/error.c +++ b/error.c @@ -1,5 +1,5 @@ /* source: error.c */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2011 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the logging subsystem */ @@ -191,6 +191,9 @@ void msg(int level, const char *format, ...) { #else /* !HAVE_GETTIMEOFDAY */ time_t now; #endif /* !HAVE_GETTIMEOFDAY */ +#if HAVE_STRFTIME + struct tm struct_tm; +#endif #define BUFLEN 512 char buff[BUFLEN], *bufp, *syslp; size_t bytes; @@ -211,11 +214,11 @@ void msg(int level, const char *format, ...) { nowt = now.tv_sec; #if HAVE_STRFTIME if (diagopts.micros) { - bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); + bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime_r(&nowt, &struct_tm)); bytes += sprintf(buff+19, "."F_tv_usec" ", now.tv_usec); } else { bytes = - strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime(&nowt)); + strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&nowt, &struct_tm)); } #else strcpy(buff, ctime(&nowt)); @@ -231,7 +234,7 @@ void msg(int level, const char *format, ...) { strcpy(buff, "unknown time "); bytes = 20; } else { #if HAVE_STRFTIME - bytes = strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime(&now)); + bytes = strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&now, &struct_tm)); #else strcpy(buff, ctime(&now)); bytes = strlen(buff);