Skip to content

Bug: SIGSEGV in SrsRtcTcpConn when WebRTC-over-TCP viewer disconnects (v6.0.184) #4642

Description

@Maqiushi

Bug: SIGSEGV in SrsRtcTcpConn when WebRTC-over-TCP viewer disconnects (v6.0.184)

Describe the bug

SRS crashes with SIGSEGV (exit code 139) every time a WebRTC-over-TCP viewer
disconnects. The crash is 100% reproducible.

Version

6.0.184 (v6.0-r0)

Environment

  • Docker: registry.cn-hangzhou.aliyuncs.com/ossrs/srs:6
  • OS: Linux x86_64
  • Config: rtmp_to_rtc on, rtc_to_rtmp on, WebRTC over TCP enabled
  • Workflow: RTMP push → SRS → WebRTC play (rtmp2rtc bridge)

To Reproduce

  1. Push an RTMP stream to SRS (e.g., via ffmpeg or custom media server)
  2. Play the stream via WebRTC over TCP in a browser
  3. Close the browser tab (or stop the WebRTC player)
  4. SRS crashes immediately with exit code 139

Kernel dmesg

srs[PID]: segfault at 10 ip 0000XXXX2a0280 sp 0000XXXXXX error 4 in srs[XXXX+664000]

Consistent binary offset: +2a0280 (relative to text section base).

addr2line

$ addr2line -e srs -f 0x5b2280
SrsRtcNetworks::tcp()
srs_app_rtc_network.cpp:84

(0x5b2280 = binary_base + 0x2a0280 + 0x312000 PIE offset)

Root Cause Analysis

The crash is a use-after-free in SrsRtcTcpConn::cycle():

// srs_app_rtc_network.cpp, SrsRtcTcpConn::cycle()
if (session_ && session_->tcp()->is_establelished()) {  // <-- crashes here
    session_->tcp()->set_state(SrsRtcNetworkStateClosed);
    session_->expire();
}

When a WebRTC viewer disconnects (DTLS close_notify):

  1. SrsRtcConnection is disposed and freed by the RTC resource manager
  2. SrsRtcTcpConn::session_ (a raw pointer) is never set to NULL
  3. Later, the TCP conn's coroutine runs and accesses session_->tcp()
  4. session_ is a dangling pointer → segfault

The session_ pointer is set in handshake() but never cleared when the
session is disposed. The same issue exists in on_tcp_pkt():

srs_error_t SrsRtcTcpConn::on_tcp_pkt(char *pkt, int nb_pkt) {
    if (!session_) return err;  // This check is useless - session_ is never set to NULL
    session_->alive();          // Dangling pointer access
    // ...
    session_->tcp()->on_stun(&ping, pkt, nb_pkt);  // Dangling pointer access
}

Suggested Fix

When SrsRtcConnection is disposed, it should notify its associated
SrsRtcTcpConn to set session_ = NULL. Or use SrsSharedPtr/weak pointer
for session_ (as the develop branch does for other objects).

Workaround

Disable WebRTC-over-TCP and use UDP only:

SRS_RTC_SERVER_TCP_ENABLED=off
SRS_RTC_SERVER_PROTOCOL=udp

Additional context

  • The v6.0.183 fix (SrsCompositeBridge iterator, commit e82dc11) is a
    different crash path and does NOT fix this issue.
  • The develop branch (v7.0) has the same vulnerable code in
    SrsRtcTcpConn::cycle() and on_tcp_pkt().
  • The crash only affects WebRTC-over-TCP. UDP transport is not affected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    TransByAITranslated by AI/GPT.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions