From d8dcde4b2345b1c685a1086d4423f0a262930c3f Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 6 Jun 2008 07:45:08 +0000 Subject: Fix hard-to-rigger locking bug in vsyslog(): SIGPIPE handler was attempting to re-acquire an already taken lock. While at it, stop checking for sigaction failure which is not possible here. Sizes: text data bss dec hex filename - 1123 13 2 1138 472 libc/misc/syslog/syslog.o + 1112 13 2 1127 467 libc/misc/syslog/syslog.o Run tested. --- libc/misc/syslog/syslog.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'libc') diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c index 05664e643..c90703ab8 100644 --- a/libc/misc/syslog/syslog.c +++ b/libc/misc/syslog/syslog.c @@ -129,7 +129,7 @@ static const struct sockaddr SyslogAddr = { static void closelog_intern(int sig) { - __UCLIBC_MUTEX_LOCK(mylock); + /* mylock must be held by the caller */ if (LogFile != -1) { (void) close(LogFile); } @@ -141,7 +141,6 @@ closelog_intern(int sig) LogFacility = LOG_USER; LogMask = 0xff; } - __UCLIBC_MUTEX_UNLOCK(mylock); } /* @@ -205,12 +204,14 @@ vsyslog(int pri, const char *fmt, va_list ap) int rc; char tbuf[1024]; /* syslogd is unable to handle longer messages */ struct sigaction action, oldaction; - int sigpipe; memset(&action, 0, sizeof(action)); action.sa_handler = closelog_intern; sigemptyset(&action.sa_mask); /* TODO: memset already zeroed it out! */ - sigpipe = sigaction(SIGPIPE, &action, &oldaction); + /* Only two errors are possible for sigaction: + * EFAULT (bad address of &oldaction) and EINVAL (invalid signo) + * none of which can happen here. */ + /*int sigpipe =*/ sigaction(SIGPIPE, &action, &oldaction); saved_errno = errno; @@ -306,7 +307,7 @@ vsyslog(int pri, const char *fmt, va_list ap) /* should mode be O_WRONLY | O_NOCTTY? -- Uli */ /* yes, but in Linux "/dev/console" never becomes ctty anyway -- vda */ if ((LogStat & LOG_CONS) && - (fd = open(_PATH_CONSOLE, O_WRONLY)) >= 0) { + (fd = open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY)) >= 0) { p = strchr(tbuf, '>') + 1; last_chr[0] = '\r'; last_chr[1] = '\n'; @@ -316,7 +317,7 @@ vsyslog(int pri, const char *fmt, va_list ap) getout: __UCLIBC_MUTEX_UNLOCK(mylock); - if (sigpipe == 0) + /*if (sigpipe == 0)*/ sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL); } libc_hidden_def(vsyslog) @@ -338,7 +339,9 @@ libc_hidden_def(syslog) void closelog(void) { + __UCLIBC_MUTEX_LOCK(mylock); closelog_intern(0); /* 0: reset LogXXX globals to default */ + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(closelog) @@ -348,9 +351,10 @@ int setlogmask(int pmask) int omask; omask = LogMask; - __UCLIBC_MUTEX_LOCK(mylock); - if (pmask != 0) + if (pmask != 0) { + __UCLIBC_MUTEX_LOCK(mylock); LogMask = pmask; - __UCLIBC_MUTEX_UNLOCK(mylock); + __UCLIBC_MUTEX_UNLOCK(mylock); + } return omask; } -- cgit v1.2.3