summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjojemann <none@none>2008-03-25 06:20:33 -0700
committerjojemann <none@none>2008-03-25 06:20:33 -0700
commit44aaa2b62b55f245416069f3c1ad5a3485d51e95 (patch)
treefa0f2955ed18d6c9161c8e880fcb99871418bc5e
parent19bd46b5d133ec3b843cb24e87bd5c84b7b062d5 (diff)
downloadillumos-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.c47
-rw-r--r--usr/src/uts/common/inet/ipf/ip_state.c17
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;