1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-30 18:06:38 +02:00

Fix ModData bug when unloading a module for good: iterate unknown_list.

When a module was unloaded (for good) that used MODDATATYPE_CLIENT
or MODDATATYPE_LOCAL_CLIENT we walked the client_list/lclient_list
and freed the moddata entry for all these clients, but we did not
walk the unknown_list, so connections in process.
That's bad, because sometimes such moddata is allocated in
HOOKTYPE_HANDSHAKE or in other routines pre-connect and since
we skipped freeing them while the module was still loaded, it
means we leak memory since it is also not freed on user exit.

Since unloading modules permanently is not a common procedure,
combined with the timing of it happening during a handshake, it
took a while before this issue was found (and then easily fixed).

There's also another moddata issue, but that is for next commit.

[skip ci]
This commit is contained in:
Bram Matthys
2023-11-10 08:05:09 +01:00
parent ec4e1d95d8
commit ffbf34fb15
+12
View File
@@ -195,6 +195,12 @@ void unload_moddata_commit(ModDataInfo *md)
md->free(&moddata_client(client, md));
memset(&moddata_client(client, md), 0, sizeof(ModData));
}
list_for_each_entry(client, &unknown_list, lclient_node)
{
if (md->free && moddata_client(client, md).ptr)
md->free(&moddata_client(client, md));
memset(&moddata_client(client, md), 0, sizeof(ModData));
}
break;
}
case MODDATATYPE_LOCAL_CLIENT:
@@ -206,6 +212,12 @@ void unload_moddata_commit(ModDataInfo *md)
md->free(&moddata_local_client(client, md));
memset(&moddata_local_client(client, md), 0, sizeof(ModData));
}
list_for_each_entry(client, &unknown_list, lclient_node)
{
if (md->free && moddata_local_client(client, md).ptr)
md->free(&moddata_local_client(client, md));
memset(&moddata_local_client(client, md), 0, sizeof(ModData));
}
break;
}
case MODDATATYPE_CHANNEL: