From 2f18f0241708f39e790db0193c6527f977a05a4e Mon Sep 17 00:00:00 2001 From: mpi Date: Tue, 27 Jun 2017 12:02:43 +0000 Subject: [PATCH] Add missing solock()/sounlock() dances around sbreserve(). While here document an abuse of parent socket's lock. Problem reported by krw@, analysis and ok bluhm@ --- sys/kern/uipc_socket.c | 8 +++++++- sys/kern/uipc_socket2.c | 7 ++++++- sys/nfs/nfs_socket.c | 4 +++- sys/nfs/nfs_syscalls.c | 6 ++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index dfdc62b78b4..c6fbdc7bc2f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.189 2017/06/26 09:32:31 mpi Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.190 2017/06/27 12:02:43 mpi Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -1635,11 +1635,14 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0) error = EINVAL; goto bad; } + s = solock(so); if (sbcheckreserve(cnt, so->so_snd.sb_wat) || sbreserve(so, &so->so_snd, cnt)) { + sounlock(s); error = ENOBUFS; goto bad; } + sounlock(s); so->so_snd.sb_wat = cnt; break; @@ -1648,11 +1651,14 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0) error = EINVAL; goto bad; } + s = solock(so); if (sbcheckreserve(cnt, so->so_rcv.sb_wat) || sbreserve(so, &so->so_rcv, cnt)) { + sounlock(s); error = ENOBUFS; goto bad; } + sounlock(s); so->so_rcv.sb_wat = cnt; break; diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 65c5dd74f65..9619cbd3dc4 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.79 2017/06/26 09:32:31 mpi Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.80 2017/06/27 12:02:43 mpi Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -148,6 +148,11 @@ sonewconn(struct socket *head, int connstatus) struct socket *so; int soqueue = connstatus ? 1 : 0; + /* + * XXXSMP as long as `so' and `head' share the same lock, we + * can call soreserve() and pr_attach() below w/o expliclitly + * locking `so'. + */ soassertlocked(head); if (mclpools[0].pr_nout > mclpools[0].pr_hardlimit * 95 / 100) diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index f12029927df..748fd82d1fc 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.118 2017/06/26 09:32:32 mpi Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.119 2017/06/27 12:02:43 mpi Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -362,7 +362,9 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR + sizeof (u_int32_t)) * 2; } + s = solock(so); error = soreserve(so, sndreserve, rcvreserve); + sounlock(s); if (error) goto bad; so->so_rcv.sb_flags |= SB_NOINTR; diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index 5d9aa6e4b5d..036d81ab761 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_syscalls.c,v 1.108 2017/05/17 08:59:05 mpi Exp $ */ +/* $OpenBSD: nfs_syscalls.c,v 1.109 2017/06/27 12:02:43 mpi Exp $ */ /* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */ /* @@ -229,7 +229,7 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam) struct nfssvc_sock *slp; struct socket *so; struct nfssvc_sock *tslp; - int error; + int s, error; so = (struct socket *)fp->f_data; tslp = NULL; @@ -247,7 +247,9 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam) siz = NFS_MAXPACKET + sizeof (u_long); else siz = NFS_MAXPACKET; + s = solock(so); error = soreserve(so, siz, siz); + sounlock(s); if (error) { m_freem(mynam); return (error); -- 2.20.1