Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Jun 2017 11:30:00 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r320052 - head/lib/libc/gen
Message-ID:  <201706171130.v5HBU0hq018797@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Jun 17 11:29:59 2017
New Revision: 320052
URL: https://svnweb.freebsd.org/changeset/base/320052

Log:
  Do not leak syslog_mutex on cancellation.
  
  Make syslog(3) resilent to cancellation occuring in supported deferred
  mode.  Code must unlock syslog_mutex on cancel, install the cleanup
  handler.
  
  Diagnosed and tested by:	eugen
  Discussed with:	dchagin
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/lib/libc/gen/syslog.c

Modified: head/lib/libc/gen/syslog.c
==============================================================================
--- head/lib/libc/gen/syslog.c	Sat Jun 17 11:25:31 2017	(r320051)
+++ head/lib/libc/gen/syslog.c	Sat Jun 17 11:29:59 2017	(r320052)
@@ -129,8 +129,8 @@ syslog(int pri, const char *fmt, ...)
 	va_end(ap);
 }
 
-void
-vsyslog(int pri, const char *fmt, va_list ap)
+static void
+vsyslog1(int pri, const char *fmt, va_list ap)
 {
 	int cnt;
 	char ch, *p;
@@ -151,13 +151,9 @@ vsyslog(int pri, const char *fmt, va_list ap)
 
 	saved_errno = errno;
 
-	THREAD_LOCK();
-
 	/* Check priority against setlogmask values. */
-	if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) {
-		THREAD_UNLOCK();
+	if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
 		return;
-	}
 
 	/* Set default facility if none specified. */
 	if ((pri & LOG_FACMASK) == 0)
@@ -167,10 +163,8 @@ vsyslog(int pri, const char *fmt, va_list ap)
 	tbuf_cookie.base = tbuf;
 	tbuf_cookie.left = sizeof(tbuf);
 	fp = fwopen(&tbuf_cookie, writehook);
-	if (fp == NULL) {
-		THREAD_UNLOCK();
+	if (fp == NULL)
 		return;
-	}
 
 	/* Build the message. */
 	(void)time(&now);
@@ -200,7 +194,6 @@ vsyslog(int pri, const char *fmt, va_list ap)
 		fmt_fp = fwopen(&fmt_cookie, writehook);
 		if (fmt_fp == NULL) {
 			fclose(fp);
-			THREAD_UNLOCK();
 			return;
 		}
 
@@ -285,10 +278,8 @@ vsyslog(int pri, const char *fmt, va_list ap)
 			 */
 			disconnectlog();
 			connectlog();
-			if (send(LogFile, tbuf, cnt, 0) >= 0) {
-				THREAD_UNLOCK();
+			if (send(LogFile, tbuf, cnt, 0) >= 0)
 				return;
-			}
 			/*
 			 * if the resend failed, fall through to
 			 * possible scenario 2
@@ -303,15 +294,11 @@ vsyslog(int pri, const char *fmt, va_list ap)
 			if (status == CONNPRIV)
 				break;
 			_usleep(1);
-			if (send(LogFile, tbuf, cnt, 0) >= 0) {
-				THREAD_UNLOCK();
+			if (send(LogFile, tbuf, cnt, 0) >= 0)
 				return;
-			}
 		}
-	} else {
-		THREAD_UNLOCK();
+	} else
 		return;
-	}
 
 	/*
 	 * Output the message to the console; try not to block
@@ -333,10 +320,25 @@ vsyslog(int pri, const char *fmt, va_list ap)
 		(void)_writev(fd, iov, 2);
 		(void)_close(fd);
 	}
+}
 
+static void
+syslog_cancel_cleanup(void *arg __unused)
+{
+
 	THREAD_UNLOCK();
 }
 
+void
+vsyslog(int pri, const char *fmt, va_list ap)
+{
+
+	THREAD_LOCK();
+	pthread_cleanup_push(syslog_cancel_cleanup, NULL);
+	vsyslog1(pri, fmt, ap);
+	pthread_cleanup_pop(1);
+}
+
 /* Should be called with mutex acquired */
 static void
 disconnectlog(void)
@@ -423,9 +425,11 @@ openlog_unlocked(const char *ident, int logstat, int l
 void
 openlog(const char *ident, int logstat, int logfac)
 {
+
 	THREAD_LOCK();
+	pthread_cleanup_push(syslog_cancel_cleanup, NULL);
 	openlog_unlocked(ident, logstat, logfac);
-	THREAD_UNLOCK();
+	pthread_cleanup_pop(1);
 }
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706171130.v5HBU0hq018797>