summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_socket.c
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-07-24 09:29:15 +0000
committermpi <mpi@openbsd.org>2017-07-24 09:29:15 +0000
commitb7ae595a98e4d2a6815c70967e5e5cbc6ceae15b (patch)
tree502f3625444bc96860612386c7776be6ab5c3878 /sys/kern/sys_socket.c
parentrt_getifa() is only needed for routing commands submited by userland. (diff)
downloadwireguard-openbsd-b7ae595a98e4d2a6815c70967e5e5cbc6ceae15b.tar.xz
wireguard-openbsd-b7ae595a98e4d2a6815c70967e5e5cbc6ceae15b.zip
Grab the socket lock in soo_ioctl() where `so_state', `so_rcv'
and `so_snd' are modified. ok bluhm@, visa@
Diffstat (limited to 'sys/kern/sys_socket.c')
-rw-r--r--sys/kern/sys_socket.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 6dfcb36ced7..d842d0bd5c1 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_socket.c,v 1.31 2017/07/20 08:25:17 mpi Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.32 2017/07/24 09:29:15 mpi Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
@@ -78,13 +78,16 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
switch (cmd) {
case FIONBIO:
+ s = solock(so);
if (*(int *)data)
so->so_state |= SS_NBIO;
else
so->so_state &= ~SS_NBIO;
- return (0);
+ sounlock(s);
+ break;
case FIOASYNC:
+ s = solock(so);
if (*(int *)data) {
so->so_state |= SS_ASYNC;
so->so_rcv.sb_flags |= SB_ASYNC;
@@ -94,43 +97,47 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
so->so_rcv.sb_flags &= ~SB_ASYNC;
so->so_snd.sb_flags &= ~SB_ASYNC;
}
- return (0);
+ sounlock(s);
+ break;
case FIONREAD:
*(int *)data = so->so_rcv.sb_datacc;
- return (0);
+ break;
case SIOCSPGRP:
so->so_pgid = *(int *)data;
so->so_siguid = p->p_ucred->cr_ruid;
so->so_sigeuid = p->p_ucred->cr_uid;
- return (0);
+ break;
case SIOCGPGRP:
*(int *)data = so->so_pgid;
- return (0);
+ break;
case SIOCATMARK:
*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
- return (0);
- }
- /*
- * Interface/routing/protocol specific ioctls:
- * interface and routing ioctls should have a
- * different entry since a socket's unnecessary
- */
- if (IOCGROUP(cmd) == 'i') {
- NET_LOCK(s);
- error = ifioctl(so, cmd, data, p);
- NET_UNLOCK(s);
- return (error);
+ break;
+
+ default:
+ /*
+ * Interface/routing/protocol specific ioctls:
+ * interface and routing ioctls should have a
+ * different entry since a socket's unnecessary
+ */
+ if (IOCGROUP(cmd) == 'i') {
+ NET_LOCK(s);
+ error = ifioctl(so, cmd, data, p);
+ NET_UNLOCK(s);
+ return (error);
+ }
+ if (IOCGROUP(cmd) == 'r')
+ return (EOPNOTSUPP);
+ s = solock(so);
+ error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ (struct mbuf *)cmd, (struct mbuf *)data, NULL, p));
+ sounlock(s);
+ break;
}
- if (IOCGROUP(cmd) == 'r')
- return (EOPNOTSUPP);
- s = solock(so);
- error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
- (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
- sounlock(s);
return (error);
}