Skip to content

Fix channel closing race condition bug#803

Open
adfoster-r7 wants to merge 1 commit into
6.5from
6.5-pre5-resolve-windows-bug
Open

Fix channel closing race condition bug#803
adfoster-r7 wants to merge 1 commit into
6.5from
6.5-pre5-resolve-windows-bug

Conversation

@adfoster-r7

@adfoster-r7 adfoster-r7 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Problem:
The windows meterpreter test/socket_channels tests would fail 90% of the time - either freezing indefinitely, or sending wrong use-after-free values back to msfconsole for channel closes - i.e. the close channel id was expected to be 4, but it could be 1960858576 in some scenarios

image

Fixes:

  • A race condition/use after free between channel closes across two threads:
    • Thread A — the scheduler waitable thread running tcp_channel_client_local_notify detects the local peer closed the socket (recv() == 0)
    • Thread B — the packet dispatcher thread processing an inbound core_channel_close request from the framework, which calls channel_destroy -> tcp_channel_client_close
  • Previously the channel id was being used as the buffer length
  • When there were issues during compilation, we'd just silently continue and ship the broken gem

Tests:

image

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets a Windows-specific stability/correctness issue in Meterpreter’s channel/socket handling, and makes the build Rake tasks fail fast when underlying commands fail.

Changes:

  • Make win_compile and java_compile abort the Rake run when make.bat/mvn fails.
  • Fix channel_write to send TLV_TYPE_LENGTH as the actual buffer length (instead of the channel id).
  • Add additional TCP/channel debug logging and mitigate a TCP client close race by nulling the channel pointer before teardown.

Impact Analysis:

  • Blast radius: high; the channel_write TLV payload is part of the core Meterpreter wire contract and affects any consumer interpreting write acknowledgements, plus TCP channel teardown on Windows (direct) and any features built atop it (transitive).
  • Data and contract effects: TLV_TYPE_LENGTH now correctly represents byte length, changing on-the-wire semantics from incorrect to correct; this should fix downstream parsing/logic that relies on TLV_TYPE_LENGTH for writes.
  • Rollback and test focus: rollback is straightforward (code-only), but validation should focus on Windows TCP channel open/write/close flows, write completion callbacks that consume TLV_TYPE_LENGTH, and repeated connect/disconnect scenarios that previously reproduced the race.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
gem/Rakefile Abort Rake tasks when Windows/Java build commands fail.
c/meterpreter/source/metsrv/channel.c Fix TLV_TYPE_LENGTH in channel_write and add channel-close debug logging.
c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c Add logging and reduce a channel teardown race by nulling ctx->channel earlier.
c/meterpreter/source/extensions/stdapi/server/net/socket/tcp_server.c Add additional server-side socket/channel debug logging.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c
Comment thread gem/Rakefile Outdated
Comment thread gem/Rakefile Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c Outdated
Comment thread c/meterpreter/source/metsrv/channel.c Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread c/meterpreter/source/metsrv/channel.c Outdated
TcpClientContext *ctx = (TcpClientContext *)context;

dprintf( "[TCP] tcp_channel_client_close. channel=0x%08X, ctx=0x%08X", channel, ctx );
dprintf("[TCP] tcp_channel_client_close. channel=0x%08X id=%u ctx=0x%08X", channel, met_api->channel.get_id(channel), ctx);
Comment thread c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c Outdated
@adfoster-r7 adfoster-r7 force-pushed the 6.5-pre5-resolve-windows-bug branch 2 times, most recently from 9aff7cf to 535842d Compare July 9, 2026 22:35
@adfoster-r7 adfoster-r7 requested a review from Copilot July 9, 2026 22:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Comment thread c/meterpreter/source/metsrv/channel.c
Comment thread c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c Outdated
Comment thread c/meterpreter/source/extensions/stdapi/server/net/socket/tcp.c Outdated
@adfoster-r7 adfoster-r7 force-pushed the 6.5-pre5-resolve-windows-bug branch from 535842d to 181a8b6 Compare July 9, 2026 22:51
// Sleep for a quarter second
// Sleep briefly to let the framework drain buffered channel data
// before we tear down the underlying socket.
Sleep(250);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is redundant, but I'll leave it in for now

}

packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel));
packet_add_tlv_uint(request, TLV_TYPE_LENGTH, length);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

Comment thread gem/Rakefile

task :win_compile do
Dir.chdir(c_source) do
system('cmd.exe /c make.bat')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when there were issues during compilation, we'd just silently continue and ship the broken gem

@adfoster-r7 adfoster-r7 changed the title 6.5 pre5 resolve windows bug Fix channel closing race condition bug Jul 10, 2026
@adfoster-r7 adfoster-r7 marked this pull request as ready for review July 10, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants