mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
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
This commit is contained in:
parent
8ed4544ca7
commit
0eb4d28bac
1 changed files with 10 additions and 10 deletions
|
|
@ -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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue