mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 20:33:46 +02:00
ctcp: cap CTCP body length used in dynamic signal name (IRC path)
The body of a CTCP message received over IRC (PRIVMSG/NOTICE) is concatenated into a dynamic signal name and emitted via signal_emit in ctcp_msg/ctcp_reply (ctcp.c) and the DCC sub-dispatch ctcp_msg_dcc/ctcp_reply_dcc (dcc.c). The first whitespace-separated token becomes the CTCP command and is interned as a signal name; the remainder is delivered to any matching handler, including loaded perl scripts. signal_emit interns unknown signal names permanently in the global signal-name registry (module_get_uniq_id_str g_strdup's the name into two hash tables that are freed only at exit). With no length or count cap on the IRC-CTCP path, a remote user sending many distinct CTCP command names grows the registry without bound, exhausting memory and crashing the victim's irssi.
This commit is contained in:
parent
43f1727ef9
commit
68131a09be
2 changed files with 24 additions and 0 deletions
|
|
@ -234,6 +234,15 @@ static void ctcp_msg(IRC_SERVER_REC *server, const char *data,
|
|||
if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_CTCPS))
|
||||
return;
|
||||
|
||||
/* Cap the CTCP body length that is concatenated into the signal name.
|
||||
* The body comes from a remote user over IRC (PRIVMSG) and is passed
|
||||
* as the second argument to any matching signal handler, including
|
||||
* loaded perl scripts. A modest cap limits the attack surface for the
|
||||
* dynamic-signal-name dispatch and aligns with the convention used for
|
||||
* CTCP-over-DCC-chat (dcc-chat.c). */
|
||||
if (strlen(data) > 256)
|
||||
return;
|
||||
|
||||
str = g_strconcat("ctcp msg ", data, NULL);
|
||||
args = strchr(str+9, ' ');
|
||||
if (args != NULL) *args++ = '\0'; else args = "";
|
||||
|
|
@ -254,6 +263,11 @@ static void ctcp_reply(IRC_SERVER_REC *server, const char *data,
|
|||
if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_CTCPS))
|
||||
return;
|
||||
|
||||
/* Cap the CTCP body length concatenated into the signal name; see
|
||||
* ctcp_msg() for the rationale. */
|
||||
if (strlen(data) > 256)
|
||||
return;
|
||||
|
||||
str = g_strconcat("ctcp reply ", data, NULL);
|
||||
args = strchr(str+11, ' ');
|
||||
if (args != NULL) *args++ = '\0'; else args = "";
|
||||
|
|
|
|||
|
|
@ -364,6 +364,11 @@ static void ctcp_msg_dcc(IRC_SERVER_REC *server, const char *data,
|
|||
if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_DCC))
|
||||
return;
|
||||
|
||||
/* Cap the CTCP body length concatenated into the signal name; see
|
||||
* ctcp_msg() in ctcp.c for the rationale. */
|
||||
if (strlen(data) > 256)
|
||||
return;
|
||||
|
||||
str = g_strconcat("ctcp msg dcc ", data, NULL);
|
||||
args = strchr(str+13, ' ');
|
||||
if (args != NULL) *args++ = '\0'; else args = "";
|
||||
|
|
@ -386,6 +391,11 @@ static void ctcp_reply_dcc(IRC_SERVER_REC *server, const char *data,
|
|||
if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_DCC))
|
||||
return;
|
||||
|
||||
/* Cap the CTCP body length concatenated into the signal name; see
|
||||
* ctcp_msg() in ctcp.c for the rationale. */
|
||||
if (strlen(data) > 256)
|
||||
return;
|
||||
|
||||
str = g_strconcat("ctcp reply dcc ", data, NULL);
|
||||
args = strchr(str+15, ' ');
|
||||
if (args != NULL) *args++ = '\0'; else args = "";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue