Author: hrs
Date: Thu May 16 19:09:41 2019
New Revision: 347887
URL: https://svnweb.freebsd.org/changeset/base/347887

Log:
  Fix hostname to be returned in an ICMPv6 NI Reply message defined
  in RFC 4620, ICMPv6 Node Information Queries.  A vnet jail with an
  IPv6 address sent a hostname of the host environment, not the
  jail, even if another hostname was set to the jail.
  
  This change can be tested by the following commands:
  
   # ifconfig epair0 create
   # jail -c -n j1 vnet host.hostname=vnetjail path=/ persist
   # ifconfig epair0b vnet j1
   # ifconfig epair0a inet6 -ifdisabled auto_linklocal up
   # jexec j1 ifconfig epair0b inet6 -ifdisabled auto_linklocal up
   # ping6 -w ff02::1%epair0a
  
  Differential Revision:        https://reviews.freebsd.org/D20207
  MFC after:    1 week

Modified:
  head/sys/netinet6/icmp6.c

Modified: head/sys/netinet6/icmp6.c
==============================================================================
--- head/sys/netinet6/icmp6.c   Thu May 16 18:54:20 2019        (r347886)
+++ head/sys/netinet6/icmp6.c   Thu May 16 19:09:41 2019        (r347887)
@@ -140,7 +140,7 @@ static int icmp6_rip6_input(struct mbuf **, int);
 static int icmp6_ratelimit(const struct in6_addr *, const int, const int);
 static const char *icmp6_redirect_diag(struct in6_addr *,
        struct in6_addr *, struct in6_addr *);
-static struct mbuf *ni6_input(struct mbuf *, int);
+static struct mbuf *ni6_input(struct mbuf *, int, struct prison *);
 static struct mbuf *ni6_nametodns(const char *, int, int);
 static int ni6_dnsmatch(const char *, int, const char *, int);
 static int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *,
@@ -627,6 +627,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
        case ICMP6_WRUREQUEST:  /* ICMP6_FQDN_QUERY */
            {
                enum { WRU, FQDN } mode;
+               struct prison *pr;
 
                if (!V_icmp6_nodeinfo)
                        break;
@@ -638,6 +639,14 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                else
                        goto badlen;
 
+               pr = NULL;
+               sx_slock(&allprison_lock);
+               TAILQ_FOREACH(pr, &allprison, pr_list)
+                       if (pr->pr_vnet == ifp->if_vnet)
+                               break; 
+               sx_sunlock(&allprison_lock);
+               if (pr == NULL)
+                       pr = curthread->td_ucred->cr_prison;
                if (mode == FQDN) {
 #ifndef PULLDOWN_TEST
                        IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
@@ -645,11 +654,10 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
 #endif
                        n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
                        if (n)
-                               n = ni6_input(n, off);
+                               n = ni6_input(n, off, pr);
                        /* XXX meaningless if n == NULL */
                        noff = sizeof(struct ip6_hdr);
                } else {
-                       struct prison *pr;
                        u_char *p;
                        int maxhlen, hlen;
 
@@ -683,13 +691,6 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                                n = NULL;
                                break;
                        }
-                       maxhlen = M_TRAILINGSPACE(n) -
-                           (sizeof(*nip6) + sizeof(*nicmp6) + 4);
-                       pr = curthread->td_ucred->cr_prison;
-                       mtx_lock(&pr->pr_mtx);
-                       hlen = strlen(pr->pr_hostname);
-                       if (maxhlen > hlen)
-                               maxhlen = hlen;
                        /*
                         * Copy IPv6 and ICMPv6 only.
                         */
@@ -699,6 +700,13 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
                        bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
                        p = (u_char *)(nicmp6 + 1);
                        bzero(p, 4);
+
+                       maxhlen = M_TRAILINGSPACE(n) -
+                           (sizeof(*nip6) + sizeof(*nicmp6) + 4);
+                       mtx_lock(&pr->pr_mtx);
+                       hlen = strlen(pr->pr_hostname);
+                       if (maxhlen > hlen)
+                               maxhlen = hlen;
                        /* meaningless TTL */
                        bcopy(pr->pr_hostname, p + 4, maxhlen);
                        mtx_unlock(&pr->pr_mtx);
@@ -1167,11 +1175,10 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int va
  *   with hostname changes by sethostname(3)
  */
 static struct mbuf *
-ni6_input(struct mbuf *m, int off)
+ni6_input(struct mbuf *m, int off, struct prison *pr)
 {
        struct icmp6_nodeinfo *ni6, *nni6;
        struct mbuf *n = NULL;
-       struct prison *pr;
        u_int16_t qtype;
        int subjlen;
        int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
@@ -1323,7 +1330,6 @@ ni6_input(struct mbuf *m, int off)
                         *   wildcard match, if gethostname(3) side has
                         *   truncated hostname.
                         */
-                       pr = curthread->td_ucred->cr_prison;
                        mtx_lock(&pr->pr_mtx);
                        n = ni6_nametodns(pr->pr_hostname,
                            strlen(pr->pr_hostname), 0);
@@ -1448,7 +1454,6 @@ ni6_input(struct mbuf *m, int off)
                /*
                 * XXX do we really have FQDN in hostname?
                 */
-               pr = curthread->td_ucred->cr_prison;
                mtx_lock(&pr->pr_mtx);
                n->m_next = ni6_nametodns(pr->pr_hostname,
                    strlen(pr->pr_hostname), oldfqdn);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to