On Fri, Jan 27, 2023 at 11:59:15AM +0300, Vitaliy Makkoveev wrote:
> It is not required for the most cases. Also, some cases could be
> protected with solock_shared().

OK bluhm@

> 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