summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-01-27 21:02:00 +0000
committerVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-01-27 21:02:00 +0000
commit290432a3677178aaf4e16e80aee383523b01c1d8 (patch)
treea07b0969f08aa15052f148c6730d2f5b115232db /sys
parent1c26d91eaa5653bd48d53ec91736a8d658e9139f (diff)
Push solock() down to sogetopt(). It is not required for the most cases.
Also, some cases could be protected with solock_shared(). ok bluhm@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_socket.c29
-rw-r--r--sys/kern/uipc_syscalls.c4
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;