diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index f8fc97939..a9bfb620e 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 7.0 Changelog +* v7.0, 2025-09-15, RTC2RTMP: Fix sequence number wraparound assertion crashes. v7.0.89 (#4491) * v7.0, 2025-09-14, Merge [#4489](https://github.com/ossrs/srs/pull/4489): Improve coverage for kernel. v7.0.88 (#4489) * v7.0, 2025-09-14, Merge [#4488](https://github.com/ossrs/srs/pull/4488): AI: Add utests for kernel and protocol. v7.0.87 (#4488) * v7.0, 2025-09-13, Merge [#4486](https://github.com/ossrs/srs/pull/4486): Move some app files to kernel. v7.0.86 (#4486) @@ -102,6 +103,8 @@ The changelog for SRS. ## SRS 6.0 Changelog +* v6.0, 2025-09-15, RTC2RTMP: Fix sequence number wraparound assertion crashes. v6.0.177 (#4491) +* v6.0, 2025-09-05, RTX: Fix race condition for timer. v6.0.176 (#4470) (#4474) * v6.0, 2025-08-26, Merge [#4451](https://github.com/ossrs/srs/pull/4451): RTC: Fix null pointer crash in RTC2RTMP when start packet is missing. v6.0.175 (#4451) * v6.0, 2025-08-16, Merge [#4441](https://github.com/ossrs/srs/pull/4441): fix err memory leak in rtc to rtmp bridge. v6.0.174 (#4441) * v6.0, 2025-08-14, Merge [#4161](https://github.com/ossrs/srs/pull/4161): fix hls & dash segments cleanup. v6.0.173 (#4161) diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 5b252c9cb..19788ff53 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1498,7 +1498,12 @@ int32_t SrsRtcFrameBuilderVideoPacketCache::find_next_lost_sn(uint16_t current_s bool SrsRtcFrameBuilderVideoPacketCache::check_frame_complete(const uint16_t start, const uint16_t end) { int16_t cnt = srs_rtp_seq_distance(start, end) + 1; - srs_assert(cnt >= 1); + + // If the sequence range is invalid (end before start), return false + if (cnt <= 0) { + srs_warn("invalid sequence range start=%u, end=%u, cnt=%d", start, end, cnt); + return false; + } uint16_t nn_fu_start = 0; uint16_t nn_fu_end = 0; diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp index 37016a7b0..a47cbcd67 100644 --- a/trunk/src/core/srs_core_version6.hpp +++ b/trunk/src/core/srs_core_version6.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 6 #define VERSION_MINOR 0 -#define VERSION_REVISION 175 +#define VERSION_REVISION 177 #endif diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index 857708202..d2ca902e7 100644 --- a/trunk/src/core/srs_core_version7.hpp +++ b/trunk/src/core/srs_core_version7.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 7 #define VERSION_MINOR 0 -#define VERSION_REVISION 88 +#define VERSION_REVISION 89 #endif \ No newline at end of file diff --git a/trunk/src/utest/srs_utest_protocol3.cpp b/trunk/src/utest/srs_utest_protocol3.cpp index fd4d96aae..78cbfc1a0 100644 --- a/trunk/src/utest/srs_utest_protocol3.cpp +++ b/trunk/src/utest/srs_utest_protocol3.cpp @@ -1021,7 +1021,7 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageStapA) EXPECT_EQ(ssrc, pkt->header.get_ssrc()); EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_); EXPECT_EQ(1000 * 90, pkt->header.get_timestamp()); // timestamp * 90 - EXPECT_FALSE(pkt->header.get_marker()); // STAP-A should not have marker bit set + EXPECT_FALSE(pkt->header.get_marker()); // STAP-A should not have marker bit set // Verify STAP-A payload was created EXPECT_TRUE(pkt->payload() != NULL); diff --git a/trunk/src/utest/srs_utest_rtc2.cpp b/trunk/src/utest/srs_utest_rtc2.cpp index b1cc8553e..2d147fcce 100644 --- a/trunk/src/utest/srs_utest_rtc2.cpp +++ b/trunk/src/utest/srs_utest_rtc2.cpp @@ -1631,3 +1631,32 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderPacketVideoRtmpNullPointerCrash) EXPECT_EQ(1, bridge.frame_count); } } + +VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderSequenceWrapAroundFix) +{ + // Test for the sequence number wraparound assertion fix + // + // ISSUE BACKGROUND: + // The check_frame_complete() used srs_rtp_seq_distance(start, end) + 1 + // and asserted that the result >= 1. However, when sequence numbers wrap around (e.g., end < start), + // srs_rtp_seq_distance can return negative values, causing the assertion to fail and crash the server. + // + // THE CRASH: + // For example, if start=5 and end=3, then srs_rtp_seq_distance(5, 3) = (int16_t)(3 - 5) = -2 + // So cnt = -2 + 1 = -1, which fails the assertion cnt >= 1 + // + // THE FIX: + // Added validation to check if cnt <= 0 and handle it gracefully: + // - check_frame_complete() returns false for invalid ranges + + SrsRtcFrameBuilderVideoPacketCache frame_builder; + + // Test check_frame_complete with wraparound sequence numbers + // This should not crash and should return false for invalid ranges + EXPECT_FALSE(frame_builder.check_frame_complete(5, 3)); // end < start + EXPECT_FALSE(frame_builder.check_frame_complete(100, 99)); // end < start + + // Valid cases should still work + EXPECT_TRUE(frame_builder.check_frame_complete(3, 3)); // same sequence + EXPECT_TRUE(frame_builder.check_frame_complete(3, 5)); // normal case +}