diff options
author | jojemann <none@none> | 2008-03-25 06:20:33 -0700 |
---|---|---|
committer | jojemann <none@none> | 2008-03-25 06:20:33 -0700 |
commit | 44aaa2b62b55f245416069f3c1ad5a3485d51e95 (patch) | |
tree | fa0f2955ed18d6c9161c8e880fcb99871418bc5e | |
parent | 19bd46b5d133ec3b843cb24e87bd5c84b7b062d5 (diff) | |
download | illumos-joyent-44aaa2b62b55f245416069f3c1ad5a3485d51e95.tar.gz |
6658611 ipfilter / panic rw_enter: bad rwlock
6675192 fr_timeoutstate stumbles over freed timeout (causing system panic) if state has age information
-rw-r--r-- | usr/src/uts/common/inet/ipf/ip_fil_solaris.c | 47 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ipf/ip_state.c | 17 |
2 files changed, 28 insertions, 36 deletions
diff --git a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c index 124f06858e..2f02a3a175 100644 --- a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c +++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c @@ -771,30 +771,29 @@ int enable; { int error; - if (enable) { - if (ifs->ifs_fr_running > 0) - error = 0; - else - error = iplattach(ifs, ns); - if (error == 0) { - if (ifs->ifs_fr_timer_id == NULL) { - int hz = drv_usectohz(500000); - - ifs->ifs_fr_timer_id = timeout(fr_slowtimer, - (void *)ifs, - hz); - } - ifs->ifs_fr_running = 1; - } else { - (void) ipldetach(ifs); - } - } else { + if (!enable) { error = ipldetach(ifs); if (error == 0) ifs->ifs_fr_running = -1; + return (error); } - return error; + if (ifs->ifs_fr_running > 0) + error = 0; + + error = iplattach(ifs, ns); + if (error == 0) { + if (ifs->ifs_fr_timer_id == NULL) { + int hz = drv_usectohz(500000); + + ifs->ifs_fr_timer_id = timeout(fr_slowtimer, + (void *)ifs, hz); + } + ifs->ifs_fr_running = 1; + } else { + (void) ipldetach(ifs); + } + return (error); } @@ -1482,21 +1481,19 @@ void fr_slowtimer __P((void *arg)) { ipf_stack_t *ifs = arg; - WRITE_ENTER(&ifs->ifs_ipf_global); - if (ifs->ifs_fr_running == -1 || ifs->ifs_fr_running == 0) { - ifs->ifs_fr_timer_id = timeout(fr_slowtimer, arg, drv_usectohz(500000)); + READ_ENTER(&ifs->ifs_ipf_global); + if (ifs->ifs_fr_running != 1) { + ifs->ifs_fr_timer_id = NULL; RWLOCK_EXIT(&ifs->ifs_ipf_global); return; } - MUTEX_DOWNGRADE(&ifs->ifs_ipf_global); - ipf_expiretokens(ifs); fr_fragexpire(ifs); fr_timeoutstate(ifs); fr_natexpire(ifs); fr_authexpire(ifs); ifs->ifs_fr_ticks++; - if (ifs->ifs_fr_running == -1 || ifs->ifs_fr_running == 1) + if (ifs->ifs_fr_running == 1) ifs->ifs_fr_timer_id = timeout(fr_slowtimer, arg, drv_usectohz(500000)); else diff --git a/usr/src/uts/common/inet/ipf/ip_state.c b/usr/src/uts/common/inet/ipf/ip_state.c index b9c0a338bb..ae46329e1d 100644 --- a/usr/src/uts/common/inet/ipf/ip_state.c +++ b/usr/src/uts/common/inet/ipf/ip_state.c @@ -3116,14 +3116,11 @@ ipf_stack_t *ifs; is->is_ref = 0; - if (is->is_tqehead[0] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0) - fr_freetimeoutqueue(is->is_tqehead[0], ifs); - } - if (is->is_tqehead[1] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[1]) == 0) - fr_freetimeoutqueue(is->is_tqehead[1], ifs); - } + if (is->is_tqehead[0] != NULL) + (void) fr_deletetimeoutqueue(is->is_tqehead[0]); + + if (is->is_tqehead[1] != NULL) + (void) fr_deletetimeoutqueue(is->is_tqehead[1]); #ifdef IPFILTER_SYNC if (is->is_sync) @@ -3176,9 +3173,7 @@ ipf_stack_t *ifs; fr_delstate(is, ISL_EXPIRE, ifs); } - for (ifq = ifs->ifs_ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - + for (ifq = ifs->ifs_ips_utqe; ifq != NULL; ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { if (tqe->tqe_die > ifs->ifs_fr_ticks) break; |