From 8cb542e3bebc16deadb429964a00cb2fd663d891 Mon Sep 17 00:00:00 2001 From: mvs Date: Fri, 27 Jan 2023 21:01:59 +0000 Subject: [PATCH] Push solock() down to sogetopt(). It is not required for the most cases. Also, some cases could be protected with solock_shared(). ok bluhm@ --- sys/kern/uipc_socket.c | 29 +++++++++++++++++++++++------ sys/kern/uipc_syscalls.c | 4 +--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index ca142be8e86..f4ef162fb1f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.298 2023/01/27 18:46:34 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.299 2023/01/27 21:01:59 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -1953,14 +1953,14 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) { int error = 0; - soassertlocked(so); - if (level != SOL_SOCKET) { if (so->so_proto->pr_ctloutput) { m->m_len = 0; + solock(so); error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so, level, optname, m); + sounlock(so); return (error); } else return (ENOPROTOOPT); @@ -1971,9 +1971,11 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) case SO_LINGER: m->m_len = sizeof (struct linger); + solock_shared(so); mtod(m, struct linger *)->l_onoff = so->so_options & SO_LINGER; mtod(m, struct linger *)->l_linger = so->so_linger; + sounlock_shared(so); break; case SO_BINDANY: @@ -1998,8 +2000,11 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) break; case SO_ERROR: + solock(so); *mtod(m, int *) = so->so_error; so->so_error = 0; + sounlock(so); + break; case SO_DOMAIN: @@ -2029,10 +2034,14 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) case SO_SNDTIMEO: case SO_RCVTIMEO: { + struct sockbuf *sb = (optname == SO_SNDTIMEO ? + &so->so_snd : &so->so_rcv); struct timeval tv; - uint64_t nsecs = (optname == SO_SNDTIMEO ? - so->so_snd.sb_timeo_nsecs : - so->so_rcv.sb_timeo_nsecs); + uint64_t nsecs; + + solock_shared(so); + nsecs = sb->sb_timeo_nsecs; + sounlock_shared(so); m->m_len = sizeof(struct timeval); memset(&tv, 0, sizeof(tv)); @@ -2050,8 +2059,10 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) so->so_proto->pr_domain; level = dom->dom_protosw->pr_protocol; + solock(so); error = (*so->so_proto->pr_ctloutput) (PRCO_GETOPT, so, level, optname, m); + sounlock(so); if (error) return (error); break; @@ -2064,7 +2075,9 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) off_t len; m->m_len = sizeof(off_t); + solock_shared(so); len = so->so_sp ? so->so_sp->ssp_len : 0; + sounlock_shared(so); memcpy(mtod(m, off_t *), &len, sizeof(off_t)); break; } @@ -2074,12 +2087,16 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) if (so->so_proto->pr_protocol == AF_UNIX) { struct unpcb *unp = sotounpcb(so); + solock(so); if (unp->unp_flags & UNP_FEIDS) { m->m_len = sizeof(unp->unp_connid); memcpy(mtod(m, caddr_t), &(unp->unp_connid), m->m_len); + sounlock(so); break; } + sounlock(so); + return (ENOTCONN); } return (EOPNOTSUPP); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 9ce55835b1e..49da6a1bab4 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.210 2023/01/27 18:46:34 mvs Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.211 2023/01/27 21:01:59 mvs Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -1271,9 +1271,7 @@ sys_getsockopt(struct proc *p, void *v, register_t *retval) valsize = 0; m = m_get(M_WAIT, MT_SOOPTS); so = fp->f_data; - solock(so); error = sogetopt(so, SCARG(uap, level), SCARG(uap, name), m); - sounlock(so); if (error == 0 && SCARG(uap, val) && valsize && m != NULL) { if (valsize > m->m_len) valsize = m->m_len; -- 2.20.1