Author: jhb
Date: Wed Jan  4 13:26:56 2012
New Revision: 229477
URL: http://svn.freebsd.org/changeset/base/229477

Log:
  In the handling of the SIOC[DG]LIFADDR icotls in in_lifaddr_ioctl(), add
  missing interface address list locking and grab a reference on the
  matching interface address after dropping the lock while it is used to
  avoid a potential use after free.
  
  Reviewed by:  bz
  MFC after:    1 week

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c       Wed Jan  4 13:23:51 2012        (r229476)
+++ head/sys/netinet/in.c       Wed Jan  4 13:26:56 2012        (r229477)
@@ -784,6 +784,7 @@ in_lifaddr_ioctl(struct socket *so, u_lo
                        }
                }
 
+               IF_ADDR_LOCK(ifp);
                TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
                        if (ifa->ifa_addr->sa_family != AF_INET)
                                continue;
@@ -794,6 +795,9 @@ in_lifaddr_ioctl(struct socket *so, u_lo
                        if (candidate.s_addr == match.s_addr)
                                break;
                }
+               if (ifa != NULL)
+                       ifa_ref(ifa);
+               IF_ADDR_UNLOCK(ifp);
                if (ifa == NULL)
                        return (EADDRNOTAVAIL);
                ia = (struct in_ifaddr *)ifa;
@@ -812,6 +816,7 @@ in_lifaddr_ioctl(struct socket *so, u_lo
                                in_mask2len(&ia->ia_sockmask.sin_addr);
 
                        iflr->flags = 0;        /*XXX*/
+                       ifa_free(ifa);
 
                        return (0);
                } else {
@@ -830,6 +835,7 @@ in_lifaddr_ioctl(struct socket *so, u_lo
                        }
                        bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
                                ia->ia_sockmask.sin_len);
+                       ifa_free(ifa);
 
                        return (in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
                            ifp, td));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to