DF-0162 / fix.diff
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -138,7 +138,15 @@ newmod->handler = data->evhand ? data->evhand : modevent_nop; newmod->arg = data->priv; bzero(&newmod->data, sizeof(newmod->data)); + /* + * Serialize against sys_modnext/modfnext/modstat/modfind readers, + * which walk `modules` under mod_token. Otherwise the TAILQ + * pointers we are about to mutate can be observed in an + * inconsistent state, corrupting the list. (DF-0162) + */ + lwkt_gettoken(&mod_token); TAILQ_INSERT_TAIL(&modules, newmod, link); + lwkt_reltoken(&mod_token); if (container == NULL) container = linker_current_file; @@ -175,7 +183,13 @@ rc = --mod->refs; if (rc == 0) { + /* + * Serialize against sys_modnext/modfnext/modstat/modfind readers + * walking `modules` under mod_token. (DF-0162) + */ + lwkt_gettoken(&mod_token); TAILQ_REMOVE(&modules, mod, link); + lwkt_reltoken(&mod_token); if (mod->file) { TAILQ_REMOVE(&mod->file->modules, mod, flink); } |