Re-resolve the forwarded channel before the half-close check

A refused channel open frees the channel and surfaces as a fatal error
rather than a close, so the guard that clears fwdChannel never runs and
the half-close check read freed memory on every refused -L forward.

- Stash the channel id wherever the channel is created or adopted
- Look the channel up by id each pass and stop once it is gone
pull/1218/head
John Safranek 2026-08-28 12:47:02 -07:00 committed by philljj
parent ad08a10ba6
commit 033646ce0a
1 changed files with 16 additions and 0 deletions

View File

@ -438,6 +438,7 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
int replyTries;
struct timeval to;
WOLFSSH_CHANNEL* fwdChannel = NULL;
word32 fwdChannelId = 0;
byte* appBuffer = NULL;
byte* sshBuffer = NULL;
word32 appBufferSz = 0;
@ -746,6 +747,7 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
if (fwdState.appFd != (SOCKET_T)-1 && newChannel != NULL) {
appFd = fwdState.appFd;
fwdChannel = newChannel;
fwdChannelId = fwdState.channelId;
FD_SET(appFd, &templateFds);
nFds = findMax((int)sshFd, (int)appFd) + 1;
appFdSet = 1;
@ -767,6 +769,16 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
break;
}
/* A refused open frees the channel and reports a fatal
* error, not a close, so the guard above does not run.
* Re-resolve by id rather than trust the pointer. */
if (fwdChannel != NULL) {
fwdChannel = wolfSSH_ChannelFind(ssh, fwdChannelId,
WS_CHANNEL_ID_SELF);
if (fwdChannel == NULL)
break;
}
/* Relay the half-close so a local reader waiting on end-of-input
* returns; nothing else relays it. Driven off the latched channel
* state, not the WS_EOF status: the flush inside wolfSSH_worker()
@ -836,6 +848,10 @@ THREAD_RETURN WOLFSSH_THREAD portfwd_worker(void* args)
appFdSet = 1;
fwdChannel = wolfSSH_ChannelFwdNew(ssh, fwdToHost, fwdToPort,
fwdFromHost, fwdFromPort);
if (fwdChannel != NULL
&& wolfSSH_ChannelGetId(fwdChannel, &fwdChannelId,
WS_CHANNEL_ID_SELF) != WS_SUCCESS)
fwdChannel = NULL;
continue;
}
if (appBufferUsed > 0) {