The branch main has been updated by rstone:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2290dfb40fce0ab46d91244282014173c7316e42

commit 2290dfb40fce0ab46d91244282014173c7316e42
Author:     Ryan Stone <rst...@freebsd.org>
AuthorDate: 2021-05-19 19:10:03 +0000
Commit:     Ryan Stone <rst...@freebsd.org>
CommitDate: 2021-06-04 17:18:11 +0000

    Enter the net epoch before calling ip6_setpktopts
    
    ip6_setpktopts() can look up ifnets via ifnet_by_index(), which
    is only safe in the net epoch.  Ensure that callers are in the net
    epoch before calling this function.
    
    Sponsored by: Dell EMC Isilon
    MFC after: 4 weeks
    Reviewed by: donner, kp
    Differential Revision: https://reviews.freebsd.org/D30630
---
 sys/netinet6/ip6_output.c  | 10 ++++++++++
 sys/netinet6/raw_ip6.c     |  8 ++++++--
 sys/netinet6/udp6_usrreq.c |  9 ++-------
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 2b49a9f7c351..71c5c4e5a501 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -2496,6 +2496,7 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct mbuf *m,
        struct ip6_pktopts *opt = *pktopt;
        int error = 0;
        struct thread *td = sopt->sopt_td;
+       struct epoch_tracker et;
 
        /* turn off any old options. */
        if (opt) {
@@ -2523,12 +2524,15 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct mbuf *m,
        }
 
        /*  set options specified by user. */
+       NET_EPOCH_ENTER(et);
        if ((error = ip6_setpktopts(m, opt, NULL, (td != NULL) ?
            td->td_ucred : NULL, so->so_proto->pr_protocol)) != 0) {
                ip6_clearpktopts(opt, -1); /* XXX: discard all options */
                free(opt, M_IP6OPT);
+               NET_EPOCH_EXIT(et);
                return (error);
        }
+       NET_EPOCH_EXIT(et);
        *pktopt = opt;
        return (0);
 }
@@ -2824,6 +2828,12 @@ ip6_setpktopts(struct mbuf *control, struct ip6_pktopts 
*opt,
        if (control == NULL || opt == NULL)
                return (EINVAL);
 
+       /*
+        * ip6_setpktopt can call ifnet_by_index(), so it's imperative that we 
are
+        * in the net epoch here.
+        */
+       NET_EPOCH_ASSERT();
+
        ip6_initpktopts(opt);
        if (stickyopt) {
                int error;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index a369abb04bfc..ad64429b5890 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -417,9 +417,13 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
        INP_WLOCK(inp);
 
        if (control != NULL) {
-               if ((error = ip6_setpktopts(control, &opt,
+               NET_EPOCH_ENTER(et);
+               error = ip6_setpktopts(control, &opt,
                    inp->in6p_outputopts, so->so_cred,
-                   so->so_proto->pr_protocol)) != 0) {
+                   so->so_proto->pr_protocol);
+               NET_EPOCH_EXIT(et);
+
+               if (error != 0) {
                        goto bad;
                }
                optp = &opt;
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 7c573d095d77..5841988f6113 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -810,21 +810,16 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf 
*m,
                return (EINVAL);
        }
 
+       NET_EPOCH_ENTER(et);
        if (control) {
                if ((error = ip6_setpktopts(control, &opt,
                    inp->in6p_outputopts, td->td_ucred, nxt)) != 0) {
-                       INP_UNLOCK(inp);
-                       ip6_clearpktopts(&opt, -1);
-                       if (control)
-                               m_freem(control);
-                       m_freem(m);
-                       return (error);
+                       goto release;
                }
                optp = &opt;
        } else
                optp = inp->in6p_outputopts;
 
-       NET_EPOCH_ENTER(et);
        if (sin6) {
                /*
                 * Since we saw no essential reason for calling in_pcbconnect,
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to