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
This commit is contained in:
parent
9576bca583
commit
cbb019b831
@ -669,6 +669,11 @@ dummynet_task(void *context, int pending)
|
||||
memset(&q, 0, sizeof(struct mq));
|
||||
CURVNET_SET(vnet_iter);
|
||||
|
||||
if (! V_dn_cfg.init_done) {
|
||||
CURVNET_RESTORE();
|
||||
continue;
|
||||
}
|
||||
|
||||
DN_BH_WLOCK();
|
||||
|
||||
/* Update number of lost(coalesced) ticks. */
|
||||
|
@ -2562,7 +2562,7 @@ ip_dn_vnet_init(void)
|
||||
{
|
||||
if (V_dn_cfg.init_done)
|
||||
return;
|
||||
V_dn_cfg.init_done = 1;
|
||||
|
||||
/* Set defaults here. MSVC does not accept initializers,
|
||||
* and this is also useful for vimages
|
||||
*/
|
||||
@ -2601,6 +2601,8 @@ ip_dn_vnet_init(void)
|
||||
|
||||
/* Initialize curr_time adjustment mechanics. */
|
||||
getmicrouptime(&V_dn_cfg.prev_t);
|
||||
|
||||
V_dn_cfg.init_done = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user