summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2009-10-20 17:55:42 +0000
committerqingli <qingli@FreeBSD.org>2009-10-20 17:55:42 +0000
commiteeb330ad1e5dc0d19dff4214fc5a6380ddd50173 (patch)
tree3c74fa53e334bf6ed6b290654dc39a2ae2673371 /sys/netinet/if_ether.c
parent8bb7f5309bf62bb21a6bc77ddbe7f2c67f8d8f0d (diff)
downloadFreeBSD-src-eeb330ad1e5dc0d19dff4214fc5a6380ddd50173.zip
FreeBSD-src-eeb330ad1e5dc0d19dff4214fc5a6380ddd50173.tar.gz
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
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 45cee89..4737b13 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -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);
OpenPOWER on IntegriCloud