From 5f892b38d892ba11a3e820bf1d103fd3cbb21085 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 26 Oct 2026 00:16:29 +0300 Subject: [PATCH] proxy: a CONNECT's request line the tail's own, not a copy A client whose fiber gave up its stack while relayed never comes back to the end of proxychild(), which frees what it allocated: the request line and the FTP base were lost with each CONNECT, the tail having a copy of the line. The line is the tail's now, taken back if mapping returns, and the FTP base is freed before mapping. Co-Authored-By: Claude Opus 5.5 --- src/proxy.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/proxy.c b/src/proxy.c index f8157d8..8b20172 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1295,10 +1295,22 @@ for(;;){ } hdrfree(&buf, &bufown); /* mapping its last thing, but in a request httpsrv hands over, whose - end is httpsrv's: the rest of the end can be a loop's */ - if(!param->onerequest && (param->maptaildata = req? (void *)strdup((char *)req) : NULL)) + end is httpsrv's: the rest of the end can be a loop's, which this + function's own may then never reach. What it would free is freed + now, and the request line is the tail's, back here if mapping + returns. */ + if(!param->onerequest && req){ + freeptr(&ftpbase); + param->maptaildata = req; + req = NULL; param->maptail = proxytail; + } param->res = mapsocket(param, param->srv->timeouts[CONNECTION_L]); + if(param->maptail == proxytail){ + req = param->maptaildata; + param->maptaildata = NULL; + param->maptail = NULL; + } RETURN(param->res); }