From 1e908917042b219b84e28a4fa561d2761e8221ce Mon Sep 17 00:00:00 2001 From: Edmund Lodewijks Date: Wed, 10 Jun 2026 10:58:55 +0200 Subject: [PATCH] Fix: copy sockinfo into local buffer before in-place split in mt_connect mt_connect() stored lua_tostring()'s return in a const char *sockinfo and, after lua_pop() had popped the argument, dispatched on the connection string by NUL-terminating its protocol prefix ('inet'/'unix'/'local') and host part in place (*p = '\0' / *at = '\0'). lua_tostring() returns a pointer into Lua-owned storage that the pop may reclaim or share with other interned strings, so both mutating it and reading it afterwards (e.g. the strlcpy into sa.sun_path and the connect() error string) are undefined behaviour. Replace the const char *sockinfo pointer with a char sockinfo[BUFRSZ] stack buffer populated via strlcpy() before lua_pop(). The in-place ':' and '@' splits now operate on memory we own. No call-site changes. Ported from the PhoenixDKIM fork of OpenDKIM. --- miltertest.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/miltertest.c b/miltertest.c index beaed18..b5bb6dc 100644 --- a/miltertest.c +++ b/miltertest.c @@ -1391,7 +1391,7 @@ mt_connect(lua_State *l) useconds_t interval = 0; char *at; char *p; - const char *sockinfo; + char sockinfo[BUFRSZ]; struct mt_context *new; assert(l != NULL); @@ -1406,7 +1406,15 @@ mt_connect(lua_State *l) lua_error(l); } - sockinfo = lua_tostring(l, 1); + /* + ** lua_tostring() returns a pointer into Lua-owned storage that the + ** lua_pop() below may reclaim or share with other interned strings. + ** The dispatch logic NUL-terminates the protocol prefix and host part + ** of this string in place, so copy it into a buffer we own first; + ** mutating the Lua-owned storage (and reading it after the pop) is + ** undefined behaviour. + */ + strlcpy(sockinfo, lua_tostring(l, 1), sizeof sockinfo); if (top == 3) { char *f;