about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-18 21:11:23 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-18 21:11:23 -0400
commitd2c604d5a40bc75fe83a62fd20377c20a73aa0d5 (patch)
treed255bb9d997ebe0b509d0f47d30f29051306c3bd
parentbe2e06d347fdb83e9c4f57e57fa29b78f6276a0c (diff)
downloadmusl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.tar.gz
musl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.tar.xz
musl-d2c604d5a40bc75fe83a62fd20377c20a73aa0d5.zip
protect syslog against cancellation
these functions are allowed to be cancellation points, but then we
would have to install cleanup handlers to avoid termination with locks
held.
-rw-r--r--src/misc/syslog.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/misc/syslog.c b/src/misc/syslog.c
index 0f757640..cbe65209 100644
--- a/src/misc/syslog.c
+++ b/src/misc/syslog.c
@@ -7,6 +7,7 @@
 #include <time.h>
 #include <signal.h>
 #include <string.h>
+#include <pthread.h>
 #include "libc.h"
 
 static int lock;
@@ -33,10 +34,13 @@ static const struct {
 
 void closelog(void)
 {
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 	LOCK(&lock);
 	close(log_fd);
 	log_fd = -1;
 	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
 }
 
 static void __openlog(const char *ident, int opt, int facility)
@@ -53,12 +57,15 @@ static void __openlog(const char *ident, int opt, int facility)
 
 void openlog(const char *ident, int opt, int facility)
 {
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 	LOCK(&lock);
 	__openlog(ident, opt, facility);
 	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
 }
 
-void __vsyslog(int priority, const char *message, va_list ap)
+static void _vsyslog(int priority, const char *message, va_list ap)
 {
 	char timebuf[16];
 	time_t now;
@@ -67,10 +74,6 @@ void __vsyslog(int priority, const char *message, va_list ap)
 	int pid;
 	int l, l2;
 
-	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
-
-	LOCK(&lock);
-
 	if (log_fd < 0) {
 		__openlog(log_ident, log_opt | LOG_NDELAY, log_facility);
 		if (log_fd < 0) {
@@ -98,6 +101,17 @@ void __vsyslog(int priority, const char *message, va_list ap)
 	UNLOCK(&lock);
 }
 
+void __vsyslog(int priority, const char *message, va_list ap)
+{
+	int cs;
+	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(&lock);
+	_vsyslog(priority, message, ap);
+	UNLOCK(&lock);
+	pthread_setcancelstate(cs, 0);
+}
+
 void syslog(int priority, const char *message, ...)
 {
 	va_list ap;