From 04e4ee4ecef3d79571fd0aabf9f7691794d54e2e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Jun 2026 18:12:07 +1000 Subject: [PATCH] log: copy forwarded message by length in rwrite(), not strlcpy() The valgrind memcheck CI flagged 'Conditional jump depends on uninitialised value(s)' in rwrite() -> strlcpy() (log.c) and the subsequent logit() fprintf. rwrite()'s daemon/logfile branch did strlcpy(msg, buf, MIN(sizeof msg, len+1)), but strlcpy() scans the whole source with strlen(); buf is the data buffer from read_a_msg() (io.c) holding exactly len bytes of a forwarded MSG_* payload with no NUL terminator, so strlen() reads past the message into uninitialised stack. Copy exactly len (bounded) bytes with memcpy() and NUL-terminate, matching the (buf, len) contract the rest of rwrite() already honours. Behaviour is unchanged for the NUL-terminated callers; the over-read is gone. Full testsuite under valgrind (1572 logs) now reports zero unsuppressed errors. --- log.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/log.c b/log.c index 5f1f3a29..3e9a2edc 100644 --- a/log.c +++ b/log.c @@ -298,7 +298,12 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8) in_block = 1; if (!log_initialised) log_init(0); - strlcpy(msg, buf, MIN((int)sizeof msg, len + 1)); + /* buf holds exactly len bytes and is not necessarily NUL-terminated + * (e.g. a forwarded MSG_* payload from read_a_msg), so copy by length + * rather than strlcpy(), which would strlen() past the end of buf. */ + int mlen = MIN((int)sizeof msg - 1, len); + memcpy(msg, buf, mlen); + msg[mlen] = '\0'; logit(priority, msg); in_block = 0;