mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
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
This commit is contained in:
parent
746e20fdb1
commit
f3990417c5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320052
@ -129,8 +129,8 @@ syslog(int pri, const char *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
vsyslog(int pri, const char *fmt, va_list ap)
|
vsyslog1(int pri, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int cnt;
|
int cnt;
|
||||||
char ch, *p;
|
char ch, *p;
|
||||||
@ -151,13 +151,9 @@ vsyslog(int pri, const char *fmt, va_list ap)
|
|||||||
|
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
THREAD_LOCK();
|
|
||||||
|
|
||||||
/* Check priority against setlogmask values. */
|
/* Check priority against setlogmask values. */
|
||||||
if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) {
|
if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Set default facility if none specified. */
|
/* Set default facility if none specified. */
|
||||||
if ((pri & LOG_FACMASK) == 0)
|
if ((pri & LOG_FACMASK) == 0)
|
||||||
@ -167,10 +163,8 @@ vsyslog(int pri, const char *fmt, va_list ap)
|
|||||||
tbuf_cookie.base = tbuf;
|
tbuf_cookie.base = tbuf;
|
||||||
tbuf_cookie.left = sizeof(tbuf);
|
tbuf_cookie.left = sizeof(tbuf);
|
||||||
fp = fwopen(&tbuf_cookie, writehook);
|
fp = fwopen(&tbuf_cookie, writehook);
|
||||||
if (fp == NULL) {
|
if (fp == NULL)
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the message. */
|
/* Build the message. */
|
||||||
(void)time(&now);
|
(void)time(&now);
|
||||||
@ -200,7 +194,6 @@ vsyslog(int pri, const char *fmt, va_list ap)
|
|||||||
fmt_fp = fwopen(&fmt_cookie, writehook);
|
fmt_fp = fwopen(&fmt_cookie, writehook);
|
||||||
if (fmt_fp == NULL) {
|
if (fmt_fp == NULL) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,10 +278,8 @@ vsyslog(int pri, const char *fmt, va_list ap)
|
|||||||
*/
|
*/
|
||||||
disconnectlog();
|
disconnectlog();
|
||||||
connectlog();
|
connectlog();
|
||||||
if (send(LogFile, tbuf, cnt, 0) >= 0) {
|
if (send(LogFile, tbuf, cnt, 0) >= 0)
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* if the resend failed, fall through to
|
* if the resend failed, fall through to
|
||||||
* possible scenario 2
|
* possible scenario 2
|
||||||
@ -303,15 +294,11 @@ vsyslog(int pri, const char *fmt, va_list ap)
|
|||||||
if (status == CONNPRIV)
|
if (status == CONNPRIV)
|
||||||
break;
|
break;
|
||||||
_usleep(1);
|
_usleep(1);
|
||||||
if (send(LogFile, tbuf, cnt, 0) >= 0) {
|
if (send(LogFile, tbuf, cnt, 0) >= 0)
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
THREAD_UNLOCK();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output the message to the console; try not to block
|
* 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)_writev(fd, iov, 2);
|
||||||
(void)_close(fd);
|
(void)_close(fd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
syslog_cancel_cleanup(void *arg __unused)
|
||||||
|
{
|
||||||
|
|
||||||
THREAD_UNLOCK();
|
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 */
|
/* Should be called with mutex acquired */
|
||||||
static void
|
static void
|
||||||
disconnectlog(void)
|
disconnectlog(void)
|
||||||
@ -423,9 +425,11 @@ openlog_unlocked(const char *ident, int logstat, int logfac)
|
|||||||
void
|
void
|
||||||
openlog(const char *ident, int logstat, int logfac)
|
openlog(const char *ident, int logstat, int logfac)
|
||||||
{
|
{
|
||||||
|
|
||||||
THREAD_LOCK();
|
THREAD_LOCK();
|
||||||
|
pthread_cleanup_push(syslog_cancel_cleanup, NULL);
|
||||||
openlog_unlocked(ident, logstat, logfac);
|
openlog_unlocked(ident, logstat, logfac);
|
||||||
THREAD_UNLOCK();
|
pthread_cleanup_pop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user