summaryrefslogtreecommitdiff
path: root/libc/misc
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-06 07:45:08 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-06 07:45:08 +0000
commitd8dcde4b2345b1c685a1086d4423f0a262930c3f (patch)
tree3c1fb9ba0cd2a7841b29da62197dfe91f26e3f65 /libc/misc
parent558bc289b787fc95146a81daf39a30fd72f9402b (diff)
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.
Diffstat (limited to 'libc/misc')
-rw-r--r--libc/misc/syslog/syslog.c22
1 files changed, 13 insertions, 9 deletions
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;
}