Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Aug 2014 19:08:12 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270347 - head/sys/netinet
Message-ID:  <201408221908.s7MJ8Csa005547@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Fri Aug 22 19:08:12 2014
New Revision: 270347
URL: http://svnweb.freebsd.org/changeset/base/270347

Log:
  Restore historical behavior of in_control, which, when no matching address
  is found, the first usable address is returned for legacy ioctls like
  SIOCGIFBRDADDR, SIOCGIFDSTADDR, SIOCGIFNETMASK and SIOCGIFADDR.
  
  While there also fix a subtle issue that a caller from a jail asking for
  INADDR_ANY may get the first IP of the host that do not belong to the jail.
  
  Submitted by:	glebius
  Differential Revision: https://reviews.freebsd.org/D667

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Fri Aug 22 18:59:19 2014	(r270346)
+++ head/sys/netinet/in.c	Fri Aug 22 19:08:12 2014	(r270347)
@@ -242,19 +242,26 @@ in_control(struct socket *so, u_long cmd
 		return (EADDRNOTAVAIL);
 
 	/*
-	 * For SIOCGIFADDR, pick the first address.  For the rest of
-	 * ioctls, try to find specified address.
+	 * Find address for this interface, if it exists.  If an
+	 * address was specified, find that one instead of the
+	 * first one on the interface, if possible.
 	 */
 	IF_ADDR_RLOCK(ifp);
 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 		if (ifa->ifa_addr->sa_family != AF_INET)
 			continue;
 		ia = (struct in_ifaddr *)ifa;
-		if (cmd == SIOCGIFADDR || addr->sin_addr.s_addr == INADDR_ANY)
-			break;
 		if (ia->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr)
 			break;
 	}
+	if (ifa == NULL)
+		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
+			if (ifa->ifa_addr->sa_family == AF_INET) {
+				ia = (struct in_ifaddr *)ifa;
+				if (prison_check_ip4(td->td_ucred,
+				    &ia->ia_addr.sin_addr) == 0)
+					break;
+			}
 
 	if (ifa == NULL) {
 		IF_ADDR_RUNLOCK(ifp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408221908.s7MJ8Csa005547>