It is not required for the most cases. Also, some cases could be
protected with solock_shared().
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.297
diff -u -p -r1.297 uipc_socket.c
--- sys/kern/uipc_socket.c 23 Jan 2023 18:34:24 -0000 1.297
+++ sys/kern/uipc_socket.c 27 Jan 2023 08:57:23 -0000
@@ -1953,14 +1953,14 @@ sogetopt(struct socket *so, int level, i
{
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, i
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, i
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, i
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, i
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, i
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, i
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);
Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.209
diff -u -p -r1.209 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c 22 Jan 2023 12:05:44 -0000 1.209
+++ sys/kern/uipc_syscalls.c 27 Jan 2023 08:57:23 -0000
@@ -1271,9 +1271,7 @@ sys_getsockopt(struct proc *p, void *v,
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;