Skip to content
Snippets Groups Projects
Commit f95f67ac authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Fix double-free race condition with SBBSCTRL upon global recycle

When multiple servers are recycling at the same time, (e.g. due to saved
change in SCFG) they'd each call sbbs_read_ini() with a shared global_startup
struct, which in turn calls sbbs_free_ini(), which would free all the
allocated network interface lists (including the global_startup one) using
iniFreeStringList (just a wrapper for strListFree), but iniFreeStringList()
does NOT modify (NULLify) the freed-pointer, so your second or third server
that called sbbs_read_ini(), with the shared MainForm->global structure, would
*again* free the same global interface list. This bug actually has always
existed because get_ini_globals() freed the global interface list in the same
way, except it *immediately* re-allocated a new one by calling
iniGetStringList(), so the time window (opportunity) for this race condition
to occur was much smaller. Truly, SBBSCTRL should use a mutex or other
mechanism to protect the shared global_startup struct, but this is a first
step to a full fix: sbbs_free_ini() should (and now does) nullify the freed
network interface pointers by using strListFree() directly. I haven't been
able to reproduce the crash upon recycle in SBBSCTRL after making this change.
parent 0efb0e9f
Branches
Tags
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #4027 passed
......@@ -308,28 +308,28 @@ void sbbs_free_ini(
)
{
if(global != NULL) {
iniFreeStringList(global->interfaces);
strListFree(&global->interfaces);
}
if(bbs != NULL) {
iniFreeStringList(bbs->telnet_interfaces);
iniFreeStringList(bbs->rlogin_interfaces);
iniFreeStringList(bbs->ssh_interfaces);
strListFree(&bbs->telnet_interfaces);
strListFree(&bbs->rlogin_interfaces);
strListFree(&bbs->ssh_interfaces);
}
if(web != NULL) {
iniFreeStringList(web->interfaces);
iniFreeStringList(web->tls_interfaces);
iniFreeStringList(web->index_file_name);
iniFreeStringList(web->cgi_ext);
strListFree(&web->interfaces);
strListFree(&web->tls_interfaces);
strListFree(&web->index_file_name);
strListFree(&web->cgi_ext);
}
if(ftp != NULL) {
iniFreeStringList(ftp->interfaces);
strListFree(&ftp->interfaces);
}
if(mail != NULL) {
iniFreeStringList(mail->interfaces);
iniFreeStringList(mail->pop3_interfaces);
strListFree(&mail->interfaces);
strListFree(&mail->pop3_interfaces);
}
if(services != NULL) {
iniFreeStringList(services->interfaces);
strListFree(&services->interfaces);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment