Where soo_ioctl() modifies `so_state', `so_rcv' or `so_snd' it needs the socket lock.
More fields might need the lock in the future but for the moment I'm concentrating on fields accessed in the TCP input path. ok? Index: kern/sys_socket.c =================================================================== RCS file: /cvs/src/sys/kern/sys_socket.c,v retrieving revision 1.30 diff -u -p -r1.30 sys_socket.c --- kern/sys_socket.c 22 Feb 2017 10:20:21 -0000 1.30 +++ kern/sys_socket.c 18 Jul 2017 06:26:15 -0000 @@ -78,13 +78,16 @@ soo_ioctl(struct file *fp, u_long cmd, c 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, c 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); }