Hi,
I've just pushed the attached patch to fix a stack-based buffer
overflow weakness (CWE-121) in syslogd in the "printline()" function
when transscribing ASCII control characters.
ASCII control characters are transliterated, e.g., an FF character is
logged as ^L, but the additional byte was not accounted for. If the
last character that could be added to the "line" buffer is an ASCII
control character, expanding it into two characters would fill all of the
allocated "line" buffer. The NUL character terminating the string inside
the "line" buffer was written one byte behind the end of the buffer.
The fix uses the same mechanism as found on both OpenBSD and FreeBSD:
additional bytes (one in the case of GNU Inetutils' syslogd) are allocated
to allow for the expansion of control characters.
On my x86_64 Ubuntu 22.04 system, this buffer overflow is not exploitable,
because a few bytes of the stack after the buffer are not used for any
data. It seems to me as if this is the case because all other variables
of the affected "printline()" function require 4 or 8 byte alignment,
as do return addresses saved on the stack for further function calls.
If someone finds a system where this weakness is exploitable, please
let us know.
Cheers,
Erik
--
Full disclosure is good for society.
-- Bruce Schneier
commit 0170cf56ca15ebd70984de9156790485afcc7a2e
Author: Erik Auerswald <[email protected]>
Date: 2025-11-23 16:39:23 +0100
syslogd: fix a stack-based buffer overflow
When logging a message, ASCII control characters are transliterated.
This transliteration uses two printable characters for each control
character. If the last character that fits into the destination
buffer is a control character, the buffer needs place for two
characters in addition to the string terminator. This was missing
from the code, resulting in a stack-based buffer overflow weakness
(CWE-121).
* NEWS: Mention fix.
* src/syslogd.c (printline): Allocate an additional byte in the
"line" buffer to account for control character transliteration.
diff --git a/NEWS b/NEWS
index 789358a4..6d65b0e8 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ GNU inetutils NEWS -- history of user-visible changes.
Thanks to Benjamin Cathelineau, see
<https://lists.gnu.org/archive/html/bug-inetutils/2025-10/msg00000.html>.
+** syslogd: Fix a stack-based buffer overflow (CWE-121).
+
* Noteworthy changes in release 2.6 (2025-02-21) [stable]
** The release tarball is now reproducible.
diff --git a/src/syslogd.c b/src/syslogd.c
index 55a8ccec..17def8d2 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1066,7 +1066,7 @@ printline (const char *hname, const char *msg)
{
int c, pri;
const char *p;
- char *q, line[MAXLINE + 1];
+ char *q, line[MAXLINE + 1 + 1];
/* test for special codes */
pri = DEFUPRI;
@@ -1093,7 +1093,7 @@ printline (const char *hname, const char *msg)
pri = LOG_MAKEPRI (LOG_USER, LOG_PRI (pri));
q = line;
- while ((c = *p++) != '\0' && q < &line[sizeof (line) - 1])
+ while ((c = *p++) != '\0' && q < &line[sizeof (line) - 1 - 1])
if (iscntrl (c))
if (c == '\n')
*q++ = ' ';