Author: qingli
Date: Tue Oct 20 21:36:56 2009
New Revision: 198308
URL: http://svn.freebsd.org/changeset/base/198308

Log:
  MFC   198301
  
  In the ARP callout timer expiration function, the current time_second
  is compared against the entry expiration time value (that was set based
  on time_second) to check if the current time is larger than the set
  expiration time. Due to the +/- timer granularity value, the comparison
  returns false, causing the alternative code to be executed. The
  alternative code path freed the memory without removing that entry
  from the table list, causing a use-after-free bug.
  
  Reviewed by:  discussed with kmacy
  Approved by:  re
  Verified by:  rnoland, yongari

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/if_ether.c

Modified: stable/8/sys/netinet/if_ether.c
==============================================================================
--- stable/8/sys/netinet/if_ether.c     Tue Oct 20 21:29:46 2009        
(r198307)
+++ stable/8/sys/netinet/if_ether.c     Tue Oct 20 21:36:56 2009        
(r198308)
@@ -168,17 +168,17 @@ arptimer(void *arg)
        ifp = lle->lle_tbl->llt_ifp;
        IF_AFDATA_LOCK(ifp);
        LLE_WLOCK(lle);
-       if (((lle->la_flags & LLE_DELETED)
-               || (time_second >= lle->la_expire))
-           && (!callout_pending(&lle->la_timer) &&
-               callout_active(&lle->la_timer)))
+       if ((!callout_pending(&lle->la_timer) &&
+           callout_active(&lle->la_timer))) {
                (void) llentry_free(lle);
+       }
+#ifdef DIAGNOSTICS
        else {
-               /*
-                * Still valid, just drop our reference
-                */
-               LLE_FREE_LOCKED(lle);
+               struct sockaddr *l3addr = L3_ADDR(lle);
+               log(LOG_INFO, "arptimer issue: %p, IPv4 address: \"%s\"\n", lle,
+                   inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
        }
+#endif
        IF_AFDATA_UNLOCK(ifp);
 }
 
@@ -365,7 +365,7 @@ retry:
 
        if (renew) {
                LLE_ADDREF(la);
-               la->la_expire = time_second;
+               la->la_expire = time_second + V_arpt_down;
                callout_reset(&la->la_timer, hz * V_arpt_down, arptimer, la);
                la->la_asked++;
                LLE_WUNLOCK(la);
_______________________________________________
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