summaryrefslogtreecommitdiffstats
path: root/sys/miscfs
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-07-24 15:07:39 +0000
committermpi <mpi@openbsd.org>2017-07-24 15:07:39 +0000
commit4416ac7ef41d0b5ecf9eb7757da62bbc80e32dd3 (patch)
tree073f4ec0e5e2aadf3d23f8871bcd48c35f2b7623 /sys/miscfs
parentMove invocations of flush_routes() and delete_addresses() from (diff)
downloadwireguard-openbsd-4416ac7ef41d0b5ecf9eb7757da62bbc80e32dd3.tar.xz
wireguard-openbsd-4416ac7ef41d0b5ecf9eb7757da62bbc80e32dd3.zip
Extend the scope of the socket lock to protect `so_state' in connect(2).
As a side effect, soconnect() and soconnect2() now expect a locked socket, so update all the callers. ok bluhm@
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/fifofs/fifo_vnops.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c
index 62b19a40fb0..7502183f931 100644
--- a/sys/miscfs/fifofs/fifo_vnops.c
+++ b/sys/miscfs/fifofs/fifo_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fifo_vnops.c,v 1.57 2017/07/08 09:19:02 mpi Exp $ */
+/* $OpenBSD: fifo_vnops.c,v 1.58 2017/07/24 15:07:39 mpi Exp $ */
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
/*
@@ -124,7 +124,7 @@ fifo_open(void *v)
struct fifoinfo *fip;
struct proc *p = ap->a_p;
struct socket *rso, *wso;
- int error;
+ int s, error;
if ((fip = vp->v_fifoinfo) == NULL) {
fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
@@ -142,7 +142,14 @@ fifo_open(void *v)
return (error);
}
fip->fi_writesock = wso;
+ /*
+ * XXXSMP
+ * We only lock `wso' because AF_LOCAL sockets are
+ * still relying on the KERNEL_LOCK().
+ */
+ s = solock(wso);
if ((error = soconnect2(wso, rso)) != 0) {
+ sounlock(s);
(void)soclose(wso);
(void)soclose(rso);
free(fip, M_VNODE, sizeof *fip);
@@ -152,11 +159,15 @@ fifo_open(void *v)
fip->fi_readers = fip->fi_writers = 0;
wso->so_state |= SS_CANTSENDMORE;
wso->so_snd.sb_lowat = PIPE_BUF;
+ } else {
+ rso = fip->fi_readsock;
+ wso = fip->fi_writesock;
+ s = solock(wso);
}
if (ap->a_mode & FREAD) {
fip->fi_readers++;
if (fip->fi_readers == 1) {
- fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
+ wso->so_state &= ~SS_CANTSENDMORE;
if (fip->fi_writers > 0)
wakeup(&fip->fi_writers);
}
@@ -165,14 +176,16 @@ fifo_open(void *v)
fip->fi_writers++;
if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
error = ENXIO;
+ sounlock(s);
goto bad;
}
if (fip->fi_writers == 1) {
- fip->fi_readsock->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
+ rso->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
if (fip->fi_readers > 0)
wakeup(&fip->fi_readers);
}
}
+ sounlock(s);
if ((ap->a_mode & O_NONBLOCK) == 0) {
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
VOP_UNLOCK(vp, p);
@@ -246,6 +259,7 @@ fifo_write(void *v)
if (ap->a_uio->uio_rw != UIO_WRITE)
panic("fifo_write mode");
#endif
+ /* XXXSMP changing state w/o lock isn't safe. */
if (ap->a_ioflag & IO_NDELAY)
wso->so_state |= SS_NBIO;
VOP_UNLOCK(ap->a_vp, p);