fixed bug that could freeze socat during signal handling

This commit is contained in:
Gerhard Rieger 2011-11-10 09:09:04 +01:00
parent 6a8f6c0734
commit 976d6f0b75
2 changed files with 13 additions and 4 deletions

View file

@ -38,6 +38,12 @@ corrections:
may result in partial writes and/or EAGAIN errors that were not handled may result in partial writes and/or EAGAIN errors that were not handled
properly but resulted in data loss or process termination. 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: ####################### V 1.7.1.3:
security: security:

11
error.c
View file

@ -1,5 +1,5 @@
/* source: error.c */ /* 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 */ /* Published under the GNU General Public License V.2, see file COPYING */
/* the logging subsystem */ /* the logging subsystem */
@ -191,6 +191,9 @@ void msg(int level, const char *format, ...) {
#else /* !HAVE_GETTIMEOFDAY */ #else /* !HAVE_GETTIMEOFDAY */
time_t now; time_t now;
#endif /* !HAVE_GETTIMEOFDAY */ #endif /* !HAVE_GETTIMEOFDAY */
#if HAVE_STRFTIME
struct tm struct_tm;
#endif
#define BUFLEN 512 #define BUFLEN 512
char buff[BUFLEN], *bufp, *syslp; char buff[BUFLEN], *bufp, *syslp;
size_t bytes; size_t bytes;
@ -211,11 +214,11 @@ void msg(int level, const char *format, ...) {
nowt = now.tv_sec; nowt = now.tv_sec;
#if HAVE_STRFTIME #if HAVE_STRFTIME
if (diagopts.micros) { 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); bytes += sprintf(buff+19, "."F_tv_usec" ", now.tv_usec);
} else { } else {
bytes = 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 #else
strcpy(buff, ctime(&nowt)); strcpy(buff, ctime(&nowt));
@ -231,7 +234,7 @@ void msg(int level, const char *format, ...) {
strcpy(buff, "unknown time "); bytes = 20; strcpy(buff, "unknown time "); bytes = 20;
} else { } else {
#if HAVE_STRFTIME #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 #else
strcpy(buff, ctime(&now)); strcpy(buff, ctime(&now));
bytes = strlen(buff); bytes = strlen(buff);