From cd0a8d29e40b865a3846ac18d224446c5c31e03a Mon Sep 17 00:00:00 2001 From: Devon Kirk Date: Wed, 1 Jul 2026 17:16:32 -0400 Subject: [PATCH] irc-cap: limit number of unique CAP signals emitted A malicious server can send an unbounded number of unique CAP tokens in CAP LS, ACK, NAK, NEW, or DEL responses. Each unique token creates a dynamic signal name via cap_emit_signal(), which is permanently interned by the signal system via module_get_uniq_id_str(). Over time this leaks memory without bound for the lifetime of the session. Fix: skip signal emission once the server has advertised more than 256 unique CAP tokens. This is a generous bound; real servers advertise 10-50 caps. --- src/irc/core/irc-cap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/irc/core/irc-cap.c b/src/irc/core/irc-cap.c index 2c2df7f9..1c5e1d18 100644 --- a/src/irc/core/irc-cap.c +++ b/src/irc/core/irc-cap.c @@ -78,7 +78,16 @@ static void cap_emit_signal (IRC_SERVER_REC *server, char *cmd, char *args) { char *signal_name; - signal_name = g_strdup_printf("server cap %s %s", cmd, args? args: ""); + if (args == NULL) + return; + + /* Cap the number of unique CAP signals emitted per server to prevent + * unbounded signal-name interning from server-controlled CAP tokens. */ + if (server->cap_supported == NULL || + g_hash_table_size(server->cap_supported) > 256) + return; + + signal_name = g_strdup_printf("server cap %s %s", cmd, args); signal_emit(signal_name, 1, server); g_free(signal_name); }