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;