Commit cbb019b8 authored by Kristof Provost's avatar Kristof Provost
Browse files

dummynet: fix ip_dn_vnet_init() / dummynet_task() race

If dummynet_task() is run on a vnet where dummynet is still initialising
(i.e. still running ip_dn_vnet_init()) we can attempt to use an
uninitialised mutex.

We can use the existing init_done field to check if the per-vnet
V_dn_cfg is fully set up, if we ensure that it's only set to 1 when
we've done all of the init work.

Reported by:	Alfredo Dal'Ava Júnior <alfredo@freebsd.org>
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D35716
parent 9576bca5
...@@ -669,6 +669,11 @@ dummynet_task(void *context, int pending) ...@@ -669,6 +669,11 @@ dummynet_task(void *context, int pending)
memset(&q, 0, sizeof(struct mq)); memset(&q, 0, sizeof(struct mq));
CURVNET_SET(vnet_iter); CURVNET_SET(vnet_iter);
if (! V_dn_cfg.init_done) {
CURVNET_RESTORE();
continue;
}
DN_BH_WLOCK(); DN_BH_WLOCK();
/* Update number of lost(coalesced) ticks. */ /* Update number of lost(coalesced) ticks. */
......
...@@ -2562,7 +2562,7 @@ ip_dn_vnet_init(void) ...@@ -2562,7 +2562,7 @@ ip_dn_vnet_init(void)
{ {
if (V_dn_cfg.init_done) if (V_dn_cfg.init_done)
return; return;
V_dn_cfg.init_done = 1;
/* Set defaults here. MSVC does not accept initializers, /* Set defaults here. MSVC does not accept initializers,
* and this is also useful for vimages * and this is also useful for vimages
*/ */
...@@ -2601,6 +2601,8 @@ ip_dn_vnet_init(void) ...@@ -2601,6 +2601,8 @@ ip_dn_vnet_init(void)
/* Initialize curr_time adjustment mechanics. */ /* Initialize curr_time adjustment mechanics. */
getmicrouptime(&V_dn_cfg.prev_t); getmicrouptime(&V_dn_cfg.prev_t);
V_dn_cfg.init_done = 1;
} }
static void static void
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment