Author: glebius
Date: Sun Dec 29 22:20:06 2013
New Revision: 260060
URL: http://svnweb.freebsd.org/changeset/base/260060

Log:
  Fix couple of bugs from r257692 related to scan of address list on
  an interface:
  - in in_control() skip over not AF_INET addresses.
  - in in_aifaddr_ioctl() and in_difaddr_ioctl() do correct check
    of address family, w/o accessing memory beyond struct ifaddr.
  
  Sponsored by: Nginx, Inc.

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c       Sun Dec 29 20:48:47 2013        (r260059)
+++ head/sys/netinet/in.c       Sun Dec 29 22:20:06 2013        (r260060)
@@ -247,6 +247,8 @@ in_control(struct socket *so, u_long cmd
         */
        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;
@@ -338,11 +340,12 @@ in_aifaddr_ioctl(u_long cmd, caddr_t dat
        ia = NULL;
        IF_ADDR_RLOCK(ifp);
        TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-               struct in_ifaddr *it = ifatoia(ifa);
+               struct in_ifaddr *it;
 
-               if (it->ia_addr.sin_family != AF_INET)
+               if (ifa->ifa_addr->sa_family != AF_INET)
                        continue;
 
+               it = (struct in_ifaddr *)ifa;
                iaIsFirst = false;
                if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
                    prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0)
@@ -530,11 +533,12 @@ in_difaddr_ioctl(caddr_t data, struct if
        ia = NULL;
        IF_ADDR_WLOCK(ifp);
        TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-               struct in_ifaddr *it = ifatoia(ifa);
+               struct in_ifaddr *it;
 
-               if (it->ia_addr.sin_family != AF_INET)
+               if (ifa->ifa_addr->sa_family != AF_INET)
                        continue;
 
+               it = (struct in_ifaddr *)ifa;
                if (deleteAny && ia == NULL && (td == NULL ||
                    prison_check_ip4(td->td_ucred, &it->ia_addr.sin_addr) == 0))
                        ia = it;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to