From 78656759179608cc583b6717cb2af281cf6db928 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Fri, 6 Mar 2026 07:00:27 +0100 Subject: [PATCH] Fix OOB write if a trusted linked server sends malicious data. NOTE: Linked servers are considered trusted in UnrealIRCd. This is not exploitable beyond a crash, due to -fstack-protector-all, a hardening compiler flag we added many years ago. Even without that flag it would be rather difficult, and i didn't manage to, but this should never happen anyway since this flag is only missing in gcc/clang versions that are more than 15 years old. This issue was introduced by the move to CMD_BIGLINES in 6c5de62c18cd625c6b03282db906333ec30c7448 in 6.2.2 release. --- doc/RELEASE-NOTES.md | 1 + src/channel.c | 4 ++-- src/modules/sjoin.c | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 09b423d81..87a209ec2 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -50,6 +50,7 @@ hardening and has quite a number of bug fixes. ### Fixes: * Crash when using [Extended Server Bans](https://www.unrealircd.org/docs/Extended_server_bans) with invalid syntax in the configuration file. +* Crash on malicious server-to-server traffic (OOB write), bug introduced in 6.2.2. * Linking could cause splitting the wrong server when a duplicate link was detected. * Don't show confusing `CENTRAL_BLOCKLIST_TIMEOUT` message when user is shunned by CBL. * Various memory leaks were fixed. Mostly a couple of bytes on `REHASH` in diff --git a/src/channel.c b/src/channel.c index 3398e52fc..670843fcc 100644 --- a/src/channel.c +++ b/src/channel.c @@ -298,8 +298,8 @@ int add_listmode_ex(Ban **list, Client *client, Channel *channel, const char *ba } /* Update/set if this ban is new or older than existing one */ - safe_strdup(ban->banstr, banid); /* cAsE may differ, use oldest version of it */ - safe_strdup(ban->who, setby); + safe_strldup(ban->banstr, banid, MAXBANLEN+1); /* cAsE may differ, use oldest version of it */ + safe_strldup(ban->who, setby, NICKLEN+USERLEN+HOSTLEN+4); ban->when = seton; return isnew ? 1 : 0; } diff --git a/src/modules/sjoin.c b/src/modules/sjoin.c index 6345d83cb..814460e8d 100644 --- a/src/modules/sjoin.c +++ b/src/modules/sjoin.c @@ -377,6 +377,9 @@ CMD_FUNC(cmd_sjoin) setby = p; sjsby_info = 1; + if (strlen(setby) > NICKLEN + USERLEN + HOSTLEN + 3) + setby[NICKLEN + USERLEN + HOSTLEN + 3] = '\0'; + tp = end; /* the remainder is used for the actual ban/exempt/invex */ }