summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormvs <mvs@openbsd.org>2021-03-18 08:43:38 +0000
committermvs <mvs@openbsd.org>2021-03-18 08:43:38 +0000
commit87131069daeaefa13c7d980a429556ff59da3ba7 (patch)
treecc7f9437860ff13fce42cad0a135958c8a4a0fe4 /sys/kern
parentFix previous (1.258). It breaks if localX itself is an object reference. (diff)
downloadwireguard-openbsd-87131069daeaefa13c7d980a429556ff59da3ba7.tar.xz
wireguard-openbsd-87131069daeaefa13c7d980a429556ff59da3ba7.zip
Unlock sendsyslog(2). Console output still requires kernel lock to be
held but this path is only followed while `syslogf' socket is not set. New `syslogf_rwlock' used to protect `syslogf' access. ok bluhm@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_log.c95
-rw-r--r--sys/kern/syscalls.master4
2 files changed, 58 insertions, 41 deletions
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index 26418a3e19a..3cfe96edb5d 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_log.c,v 1.73 2021/03/09 15:08:23 bluhm Exp $ */
+/* $OpenBSD: subr_log.c,v 1.74 2021/03/18 08:43:38 mvs Exp $ */
/* $NetBSD: subr_log.c,v 1.11 1996/03/30 22:24:44 christos Exp $ */
/*
@@ -86,7 +86,9 @@ int log_open; /* also used in log() */
int msgbufmapped; /* is the message buffer mapped */
struct msgbuf *msgbufp; /* the mapped buffer, itself. */
struct msgbuf *consbufp; /* console message buffer. */
+
struct file *syslogf;
+struct rwlock syslogf_rwlock = RWLOCK_INITIALIZER("syslogf");
/*
* Lock that serializes access to log message buffers.
@@ -215,8 +217,11 @@ logclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct file *fp;
+ rw_enter_write(&syslogf_rwlock);
fp = syslogf;
syslogf = NULL;
+ rw_exit(&syslogf_rwlock);
+
if (fp)
FRELE(fp, p);
log_open = 0;
@@ -407,7 +412,7 @@ out:
int
logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct proc *p)
{
- struct file *fp;
+ struct file *fp, *newfp;
int error;
switch (com) {
@@ -441,9 +446,14 @@ logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct proc *p)
case LIOCSFD:
if ((error = suser(p)) != 0)
return (error);
- fp = syslogf;
- if ((error = getsock(p, *(int *)data, &syslogf)) != 0)
+ if ((error = getsock(p, *(int *)data, &newfp)) != 0)
return (error);
+
+ rw_enter_write(&syslogf_rwlock);
+ fp = syslogf;
+ syslogf = newfp;
+ rw_exit(&syslogf_rwlock);
+
if (fp)
FRELE(fp, p);
break;
@@ -635,12 +645,15 @@ dosendsyslog(struct proc *p, const char *buf, size_t nbyte, int flags,
int error;
/* Global variable syslogf may change during sleep, use local copy. */
+ rw_enter_read(&syslogf_rwlock);
fp = syslogf;
if (fp)
FREF(fp);
- else if (!ISSET(flags, LOG_CONS))
- return (ENOTCONN);
- else {
+ rw_exit(&syslogf_rwlock);
+
+ if (fp == NULL) {
+ if (!ISSET(flags, LOG_CONS))
+ return (ENOTCONN);
/*
* Strip off syslog priority when logging to console.
* LOG_PRIMASK | LOG_FACMASK is 0x03ff, so at most 4
@@ -690,41 +703,45 @@ dosendsyslog(struct proc *p, const char *buf, size_t nbyte, int flags,
error = sosend(fp->f_data, NULL, &auio, NULL, NULL, flags);
if (error == 0)
len -= auio.uio_resid;
- } else if (constty || cn_devvp) {
- error = cnwrite(0, &auio, 0);
- if (error == 0)
- len -= auio.uio_resid;
- aiov.iov_base = "\r\n";
- aiov.iov_len = 2;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_WRITE;
- auio.uio_procp = p;
- auio.uio_offset = 0;
- auio.uio_resid = aiov.iov_len;
- cnwrite(0, &auio, 0);
} else {
- /* XXX console redirection breaks down... */
- if (sflg == UIO_USERSPACE) {
- kbuf = malloc(len, M_TEMP, M_WAITOK);
- error = copyin(aiov.iov_base, kbuf, len);
+ KERNEL_LOCK();
+ if (constty || cn_devvp) {
+ error = cnwrite(0, &auio, 0);
+ if (error == 0)
+ len -= auio.uio_resid;
+ aiov.iov_base = "\r\n";
+ aiov.iov_len = 2;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_procp = p;
+ auio.uio_offset = 0;
+ auio.uio_resid = aiov.iov_len;
+ cnwrite(0, &auio, 0);
} else {
- kbuf = aiov.iov_base;
- error = 0;
- }
- if (error == 0)
- for (i = 0; i < len; i++) {
- if (kbuf[i] == '\0')
- break;
- cnputc(kbuf[i]);
- auio.uio_resid--;
+ /* XXX console redirection breaks down... */
+ if (sflg == UIO_USERSPACE) {
+ kbuf = malloc(len, M_TEMP, M_WAITOK);
+ error = copyin(aiov.iov_base, kbuf, len);
+ } else {
+ kbuf = aiov.iov_base;
+ error = 0;
}
- if (sflg == UIO_USERSPACE)
- free(kbuf, M_TEMP, len);
- if (error == 0)
- len -= auio.uio_resid;
- cnputc('\n');
+ if (error == 0)
+ for (i = 0; i < len; i++) {
+ if (kbuf[i] == '\0')
+ break;
+ cnputc(kbuf[i]);
+ auio.uio_resid--;
+ }
+ if (sflg == UIO_USERSPACE)
+ free(kbuf, M_TEMP, len);
+ if (error == 0)
+ len -= auio.uio_resid;
+ cnputc('\n');
+ }
+ KERNEL_UNLOCK();
}
#ifdef KTRACE
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 6ba28a2b095..33758258899 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
-; $OpenBSD: syscalls.master,v 1.208 2021/01/18 18:25:51 mvs Exp $
+; $OpenBSD: syscalls.master,v 1.209 2021/03/18 08:43:38 mvs Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -235,7 +235,7 @@
fd_set *ex, const struct timespec *ts, \
const sigset_t *mask); }
111 STD { int sys_sigsuspend(int mask); }
-112 STD { int sys_sendsyslog(const char *buf, size_t nbyte, \
+112 STD NOLOCK { int sys_sendsyslog(const char *buf, size_t nbyte, \
int flags); }
113 UNIMPL fktrace
114 STD { int sys_unveil(const char *path, \