Fix kern/39769: race condition in TCP timers
When a TCP timer is disarmed (with callout_stop()) in the general case callout_invoking() isn't checked, so the timer handler could be called run when the current interrupt handler exits, athough the timer is disarmed. This case cause bad things like TCPT_REXMT and TCPT_PERSIST being both pending, causing a panic (see the PR for details). Close the issue by aborting the handler if the timer is not callout_expired(). (the EXPIRED flag being cleared by callout_stop()).
This commit is contained in:
parent
3ab32a0a5e
commit
71d4948e50
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_timer.c,v 1.82 2008/10/10 10:21:05 ad Exp $ */
|
||||
/* $NetBSD: tcp_timer.c,v 1.83 2008/11/09 17:32:38 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -93,7 +93,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.82 2008/10/10 10:21:05 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.83 2008/11/09 17:32:38 bouyer Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_tcp_debug.h"
|
||||
|
@ -212,6 +212,10 @@ tcp_delack(void *arg)
|
|||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (!callout_expired(&tp->t_delack_ch)) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
tp->t_flags |= TF_ACKNOW;
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
@ -271,6 +275,10 @@ tcp_timer_rexmt(void *arg)
|
|||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (!callout_expired(&tp->t_timer[TCPT_REXMT])) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if ((tp->t_flags & TF_PMTUD_PEND) && tp->t_inpcb &&
|
||||
|
@ -428,6 +436,10 @@ tcp_timer_persist(void *arg)
|
|||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (!callout_expired(&tp->t_timer[TCPT_PERSIST])) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
#ifdef TCP_DEBUG
|
||||
|
@ -495,6 +507,10 @@ tcp_timer_keep(void *arg)
|
|||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (!callout_expired(&tp->t_timer[TCPT_KEEP])) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
|
@ -585,6 +601,10 @@ tcp_timer_2msl(void *arg)
|
|||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (!callout_expired(&tp->t_timer[TCPT_2MSL])) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2 MSL timeout went off, clear the SACK scoreboard, reset
|
||||
|
|
Loading…
Reference in New Issue