diff options
author | 2020-09-29 11:48:54 +0000 | |
---|---|---|
committer | 2020-09-29 11:48:54 +0000 | |
commit | 27257b4ae4e10c6fd37c4d6e3022c973aa12a97a (patch) | |
tree | a1353c6a73bacddf2593ed639a757d88448245d9 | |
parent | Introduce a helper to check if all available swap is in use. (diff) | |
download | wireguard-openbsd-27257b4ae4e10c6fd37c4d6e3022c973aa12a97a.tar.xz wireguard-openbsd-27257b4ae4e10c6fd37c4d6e3022c973aa12a97a.zip |
Move the solock() call outside of solisten(). The reason is that the
so_state and splice checks were done without the proper lock which is
incorrect. This is similar to sobind(), soconnect() which also require
the callee to hold the socket lock.
Found by, with and OK mvs@, OK mpi@
-rw-r--r-- | sys/kern/uipc_socket.c | 12 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 6 |
2 files changed, 9 insertions, 9 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index dc1c6be333e..227e1ded9ca 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.248 2020/08/07 14:35:38 cheloha Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.249 2020/09/29 11:48:54 claudio Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -192,7 +192,9 @@ sobind(struct socket *so, struct mbuf *nam, struct proc *p) int solisten(struct socket *so, int backlog) { - int s, error; + int error; + + soassertlocked(so); if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING)) return (EINVAL); @@ -200,13 +202,10 @@ solisten(struct socket *so, int backlog) if (isspliced(so) || issplicedback(so)) return (EOPNOTSUPP); #endif /* SOCKET_SPLICE */ - s = solock(so); error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL, curproc); - if (error) { - sounlock(so, s); + if (error) return (error); - } if (TAILQ_FIRST(&so->so_q) == NULL) so->so_options |= SO_ACCEPTCONN; if (backlog < 0 || backlog > somaxconn) @@ -214,7 +213,6 @@ solisten(struct socket *so, int backlog) if (backlog < sominconn) backlog = sominconn; so->so_qlimit = backlog; - sounlock(so, s); return (0); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 6cd0cb04282..0b372dec7f3 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.186 2020/06/10 13:24:57 visa Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.187 2020/09/29 11:48:54 claudio Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -194,12 +194,14 @@ sys_listen(struct proc *p, void *v, register_t *retval) } */ *uap = v; struct file *fp; struct socket *so; - int error; + int s, error; if ((error = getsock(p, SCARG(uap, s), &fp)) != 0) return (error); so = fp->f_data; + s = solock(so); error = solisten(so, SCARG(uap, backlog)); + sounlock(so, s); FRELE(fp, p); return (error); } |