From owner-svn-src-head@FreeBSD.ORG Tue Oct 20 17:55:42 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A4CC1106566B; Tue, 20 Oct 2009 17:55:42 +0000 (UTC) (envelope-from qingli@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 940A88FC1A; Tue, 20 Oct 2009 17:55:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n9KHtgZI073968; Tue, 20 Oct 2009 17:55:42 GMT (envelope-from qingli@svn.freebsd.org) Received: (from qingli@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n9KHtgT9073966; Tue, 20 Oct 2009 17:55:42 GMT (envelope-from qingli@svn.freebsd.org) Message-Id: <200910201755.n9KHtgT9073966@svn.freebsd.org> From: Qing Li Date: Tue, 20 Oct 2009 17:55:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198301 - head/sys/netinet X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Oct 2009 17:55:42 -0000 Author: qingli Date: Tue Oct 20 17:55:42 2009 New Revision: 198301 URL: http://svn.freebsd.org/changeset/base/198301 Log: 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 MFC after: immediately Verified by: rnoland, yongari Modified: head/sys/netinet/if_ether.c Modified: head/sys/netinet/if_ether.c ============================================================================== --- head/sys/netinet/if_ether.c Tue Oct 20 17:50:36 2009 (r198300) +++ head/sys/netinet/if_ether.c Tue Oct 20 17:55:42 2009 (r198301) @@ -175,18 +175,18 @@ arptimer(void *arg) CURVNET_SET(ifp->if_vnet); IF_AFDATA_LOCK(ifp); LLE_WLOCK(lle); - if (((lle->la_flags & LLE_DELETED) || - (time_second >= lle->la_expire)) && - (!callout_pending(&lle->la_timer) && + if ((!callout_pending(&lle->la_timer) && callout_active(&lle->la_timer))) { (void) llentry_free(lle); ARPSTAT_INC(timeouts); - } else { - /* - * Still valid, just drop our reference - */ - LLE_FREE_LOCKED(lle); + } +#ifdef DIAGNOSTICS + else { + 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); CURVNET_RESTORE(); } @@ -377,7 +377,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);