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;

Reply via email to