On Sat, Jul 22, 2023 at 05:42:49PM +0300, Vitaliy Makkoveev wrote:
> Thanks for testing. There is updated diff below.
OK bluhm@
> Index: sys/kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.305
> diff -u -p -r1.305 uipc_socket.c
> --- sys/kern/uipc_socket.c 4 Jul 2023 22:28:24 -0000 1.305
> +++ sys/kern/uipc_socket.c 22 Jul 2023 14:38:43 -0000
> @@ -1789,12 +1789,12 @@ sosetopt(struct socket *so, int level, i
> {
> int error = 0;
>
> - soassertlocked(so);
> -
> if (level != SOL_SOCKET) {
> if (so->so_proto->pr_ctloutput) {
> + solock(so);
> error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> level, optname, m);
> + sounlock(so);
> return (error);
> }
> error = ENOPROTOOPT;
> @@ -1813,9 +1813,16 @@ sosetopt(struct socket *so, int level, i
> mtod(m, struct linger *)->l_linger < 0 ||
> mtod(m, struct linger *)->l_linger > SHRT_MAX)
> return (EINVAL);
> +
> + solock(so);
> so->so_linger = mtod(m, struct linger *)->l_linger;
> - /* FALLTHROUGH */
> + if (*mtod(m, int *))
> + so->so_options |= optname;
> + else
> + so->so_options &= ~optname;
> + sounlock(so);
>
> + break;
> case SO_BINDANY:
> case SO_DEBUG:
> case SO_KEEPALIVE:
> @@ -1828,12 +1835,15 @@ sosetopt(struct socket *so, int level, i
> case SO_ZEROIZE:
> if (m == NULL || m->m_len < sizeof (int))
> return (EINVAL);
> +
> + solock(so);
> if (*mtod(m, int *))
> so->so_options |= optname;
> else
> so->so_options &= ~optname;
> - break;
> + sounlock(so);
>
> + break;
> case SO_DONTROUTE:
> if (m == NULL || m->m_len < sizeof (int))
> return (EINVAL);
> @@ -1853,23 +1863,32 @@ sosetopt(struct socket *so, int level, i
> cnt = *mtod(m, int *);
> if ((long)cnt <= 0)
> cnt = 1;
> - switch (optname) {
>
> + solock(so);
> + switch (optname) {
> case SO_SNDBUF:
> - if (so->so_snd.sb_state & SS_CANTSENDMORE)
> - return (EINVAL);
> + if (so->so_snd.sb_state & SS_CANTSENDMORE) {
> + error = EINVAL;
> + break;
> + }
> if (sbcheckreserve(cnt, so->so_snd.sb_wat) ||
> - sbreserve(so, &so->so_snd, cnt))
> - return (ENOBUFS);
> + sbreserve(so, &so->so_snd, cnt)) {
> + error = ENOBUFS;
> + break;
> + }
> so->so_snd.sb_wat = cnt;
> break;
>
> case SO_RCVBUF:
> - if (so->so_rcv.sb_state & SS_CANTRCVMORE)
> - return (EINVAL);
> + if (so->so_rcv.sb_state & SS_CANTRCVMORE) {
> + error = EINVAL;
> + break;
> + }
> if (sbcheckreserve(cnt, so->so_rcv.sb_wat) ||
> - sbreserve(so, &so->so_rcv, cnt))
> - return (ENOBUFS);
> + sbreserve(so, &so->so_rcv, cnt)) {
> + error = ENOBUFS;
> + break;
> + }
> so->so_rcv.sb_wat = cnt;
> break;
>
> @@ -1884,6 +1903,7 @@ sosetopt(struct socket *so, int level, i
> so->so_rcv.sb_hiwat : cnt;
> break;
> }
> + sounlock(so);
> break;
> }
>
> @@ -1903,8 +1923,9 @@ sosetopt(struct socket *so, int level, i
> return (EDOM);
> if (nsecs == 0)
> nsecs = INFSLP;
> - switch (optname) {
>
> + solock(so);
> + switch (optname) {
> case SO_SNDTIMEO:
> so->so_snd.sb_timeo_nsecs = nsecs;
> break;
> @@ -1912,6 +1933,7 @@ sosetopt(struct socket *so, int level, i
> so->so_rcv.sb_timeo_nsecs = nsecs;
> break;
> }
> + sounlock(so);
> break;
> }
>
> @@ -1923,19 +1945,20 @@ sosetopt(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_SETOPT, so, level, optname, m);
> - return (error);
> - }
> - error = ENOPROTOOPT;
> + sounlock(so);
> + } else
> + error = ENOPROTOOPT;
> break;
> -
> #ifdef SOCKET_SPLICE
> case SO_SPLICE:
> + solock(so);
> if (m == NULL) {
> error = sosplice(so, -1, 0, NULL);
> } else if (m->m_len < sizeof(int)) {
> - return (EINVAL);
> + error = EINVAL;
> } else if (m->m_len < sizeof(struct splice)) {
> error = sosplice(so, *mtod(m, int *), 0, NULL);
> } else {
> @@ -1944,16 +1967,13 @@ sosetopt(struct socket *so, int level, i
> mtod(m, struct splice *)->sp_max,
> &mtod(m, struct splice *)->sp_idle);
> }
> + sounlock(so);
> break;
> #endif /* SOCKET_SPLICE */
>
> default:
> error = ENOPROTOOPT;
> break;
> - }
> - if (error == 0 && so->so_proto->pr_ctloutput) {
> - (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> - level, optname, m);
> }
> }
>
> Index: sys/kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.212
> diff -u -p -r1.212 uipc_syscalls.c
> --- sys/kern/uipc_syscalls.c 10 Feb 2023 14:34:17 -0000 1.212
> +++ sys/kern/uipc_syscalls.c 22 Jul 2023 14:38:43 -0000
> @@ -1232,9 +1232,7 @@ sys_setsockopt(struct proc *p, void *v,
> m->m_len = SCARG(uap, valsize);
> }
> so = fp->f_data;
> - solock(so);
> error = sosetopt(so, SCARG(uap, level), SCARG(uap, name), m);
> - sounlock(so);
> bad:
> m_freem(m);
> FRELE(fp, p);
> Index: sys/net/bfd.c
> ===================================================================
> RCS file: /cvs/src/sys/net/bfd.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 bfd.c
> --- sys/net/bfd.c 12 Jul 2023 16:10:45 -0000 1.79
> +++ sys/net/bfd.c 22 Jul 2023 14:38:43 -0000
> @@ -452,9 +452,7 @@ bfd_listener(struct bfd_config *bfd, uns
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = MAXTTL;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_MINTTL, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> @@ -531,9 +529,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = IP_PORTRANGE_HIGH;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> @@ -545,9 +541,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = MAXTTL;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_TTL, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> @@ -559,9 +553,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = IPTOS_PREC_INTERNETCONTROL;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_TOS, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> Index: sys/net/if_vxlan.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_vxlan.c,v
> retrieving revision 1.92
> diff -u -p -r1.92 if_vxlan.c
> --- sys/net/if_vxlan.c 13 Apr 2023 02:19:05 -0000 1.92
> +++ sys/net/if_vxlan.c 22 Jul 2023 14:38:43 -0000
> @@ -934,9 +934,9 @@ vxlan_tep_add_addr(struct vxlan_softc *s
> goto free;
>
> solock(so);
> -
> sotoinpcb(so)->inp_upcall = vxlan_input;
> sotoinpcb(so)->inp_upcall_arg = vt;
> + sounlock(so);
>
> m_inithdr(&m);
> m.m_len = sizeof(vt->vt_rdomain);
> @@ -973,12 +973,12 @@ vxlan_tep_add_addr(struct vxlan_softc *s
> unhandled_af(vt->vt_af);
> }
>
> + solock(so);
> error = sobind(so, &m, curproc);
> + sounlock(so);
> if (error != 0)
> goto close;
>
> - sounlock(so);
> -
> rw_assert_wrlock(&vxlan_lock);
> TAILQ_INSERT_TAIL(&vxlan_teps, vt, vt_entry);
>
> @@ -987,7 +987,6 @@ vxlan_tep_add_addr(struct vxlan_softc *s
> return (0);
>
> close:
> - sounlock(so);
> soclose(so, MSG_DONTWAIT);
> free:
> free(vt, M_DEVBUF, sizeof(*vt));
> Index: sys/net/if_wg.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_wg.c,v
> retrieving revision 1.28
> diff -u -p -r1.28 if_wg.c
> --- sys/net/if_wg.c 1 Jun 2023 18:57:53 -0000 1.28
> +++ sys/net/if_wg.c 22 Jul 2023 14:38:43 -0000
> @@ -720,14 +720,16 @@ wg_socket_open(struct socket **so, int a
> solock(*so);
> sotoinpcb(*so)->inp_upcall = wg_input;
> sotoinpcb(*so)->inp_upcall_arg = upcall_arg;
> + sounlock(*so);
>
> if ((ret = sosetopt(*so, SOL_SOCKET, SO_RTABLE, &mrtable)) == 0) {
> + solock(*so);
> if ((ret = sobind(*so, &mhostnam, curproc)) == 0) {
> *port = sotoinpcb(*so)->inp_lport;
> *rtable = sotoinpcb(*so)->inp_rtableid;
> }
> + sounlock(*so);
> }
> - sounlock(*so);
>
> if (ret != 0)
> wg_socket_close(so);
> Index: sys/nfs/krpc_subr.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/krpc_subr.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 krpc_subr.c
> --- sys/nfs/krpc_subr.c 6 Jun 2022 14:45:41 -0000 1.37
> +++ sys/nfs/krpc_subr.c 22 Jul 2023 14:38:43 -0000
> @@ -239,9 +239,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> tv.tv_usec = 0;
> memcpy(mtod(m, struct timeval *), &tv, sizeof tv);
> m->m_len = sizeof(tv);
> - solock(so);
> error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m);
> - sounlock(so);
> m_freem(m);
> if (error)
> goto out;
> @@ -255,9 +253,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> on = mtod(m, int32_t *);
> m->m_len = sizeof(*on);
> *on = 1;
> - solock(so);
> error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m);
> - sounlock(so);
> m_freem(m);
> if (error)
> goto out;
> @@ -272,9 +268,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = IP_PORTRANGE_LOW;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error)
> goto out;
> @@ -299,9 +293,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> mopt->m_len = sizeof(int);
> ip = mtod(mopt, int *);
> *ip = IP_PORTRANGE_DEFAULT;
> - solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> - sounlock(so);
> m_freem(mopt);
> if (error)
> goto out;
> Index: sys/nfs/nfs_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_socket.c,v
> retrieving revision 1.143
> diff -u -p -r1.143 nfs_socket.c
> --- sys/nfs/nfs_socket.c 13 Aug 2022 21:01:46 -0000 1.143
> +++ sys/nfs/nfs_socket.c 22 Jul 2023 14:38:43 -0000
> @@ -258,7 +258,6 @@ nfs_connect(struct nfsmount *nmp, struct
> MGET(nam, M_WAIT, MT_SONAME);
>
> so = nmp->nm_so;
> - solock(so);
> nmp->nm_soflags = so->so_proto->pr_flags;
>
> /*
> @@ -282,7 +281,9 @@ nfs_connect(struct nfsmount *nmp, struct
> sin->sin_family = AF_INET;
> sin->sin_addr.s_addr = INADDR_ANY;
> sin->sin_port = htons(0);
> + solock(so);
> error = sobind(so, nam, &proc0);
> + sounlock(so);
> if (error)
> goto bad;
>
> @@ -294,6 +295,7 @@ nfs_connect(struct nfsmount *nmp, struct
> goto bad;
> }
>
> + solock(so);
> /*
> * Protocols that do not require connections may be optionally left
> * unconnected for servers that reply from a port other than NFS_PORT.
> @@ -301,12 +303,12 @@ nfs_connect(struct nfsmount *nmp, struct
> if (nmp->nm_flag & NFSMNT_NOCONN) {
> if (nmp->nm_soflags & PR_CONNREQUIRED) {
> error = ENOTCONN;
> - goto bad;
> + goto bad_locked;
> }
> } else {
> error = soconnect(so, nmp->nm_nam);
> if (error)
> - goto bad;
> + goto bad_locked;
>
> /*
> * Wait for the connection to complete. Cribbed from the
> @@ -320,13 +322,13 @@ nfs_connect(struct nfsmount *nmp, struct
> so->so_error == 0 && rep &&
> (error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
> so->so_state &= ~SS_ISCONNECTING;
> - goto bad;
> + goto bad_locked;
> }
> }
> if (so->so_error) {
> error = so->so_error;
> so->so_error = 0;
> - goto bad;
> + goto bad_locked;
> }
> }
> /*
> @@ -338,6 +340,7 @@ nfs_connect(struct nfsmount *nmp, struct
> so->so_snd.sb_timeo_nsecs = SEC_TO_NSEC(5);
> else
> so->so_snd.sb_timeo_nsecs = INFSLP;
> + sounlock(so);
> if (nmp->nm_sotype == SOCK_DGRAM) {
> sndreserve = nmp->nm_wsize + NFS_MAXPKTHDR;
> rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
> @@ -360,9 +363,10 @@ nfs_connect(struct nfsmount *nmp, struct
> } else {
> panic("%s: nm_sotype %d", __func__, nmp->nm_sotype);
> }
> + solock(so);
> error = soreserve(so, sndreserve, rcvreserve);
> if (error)
> - goto bad;
> + goto bad_locked;
> so->so_rcv.sb_flags |= SB_NOINTR;
> so->so_snd.sb_flags |= SB_NOINTR;
> sounlock(so);
> @@ -377,8 +381,9 @@ nfs_connect(struct nfsmount *nmp, struct
> nmp->nm_timeouts = 0;
> return (0);
>
> -bad:
> +bad_locked:
> sounlock(so);
> +bad:
>
> m_freem(mopt);
> m_freem(nam);
> Index: sys/nfs/nfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_syscalls.c,v
> retrieving revision 1.118
> diff -u -p -r1.118 nfs_syscalls.c
> --- sys/nfs/nfs_syscalls.c 6 Jun 2022 14:45:41 -0000 1.118
> +++ sys/nfs/nfs_syscalls.c 22 Jul 2023 14:38:43 -0000
> @@ -249,8 +249,8 @@ nfssvc_addsock(struct file *fp, struct m
> siz = NFS_MAXPACKET;
> solock(so);
> error = soreserve(so, siz, siz);
> + sounlock(so);
> if (error) {
> - sounlock(so);
> m_freem(mynam);
> return (error);
> }
> @@ -275,6 +275,7 @@ nfssvc_addsock(struct file *fp, struct m
> sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
> m_freem(m);
> }
> + solock(so);
> so->so_rcv.sb_flags &= ~SB_NOINTR;
> so->so_rcv.sb_timeo_nsecs = INFSLP;
> so->so_snd.sb_flags &= ~SB_NOINTR;