Hi Santiago,

On 11/9/26 14:23, Santiago Ruano Rincón wrote:
[snip]
diff -Nru srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch 
srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch
--- srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch      1969-12-31 
18:00:00.000000000 -0600
+++ srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch      2026-11-06 
09:52:27.000000000 -0600
@@ -0,0 +1,31 @@
+Origin: 
https://github.com/Haivision/srt/commit/e020c3bb8e04e204b36f9fb56cdcbb6756cd0d28

AFAICS, these changes were not included into trixie. Do you know why?

Trixie already includes the check in CVE-2026-55868.patch, not 
CVE-2026-55869.patch. My proposed Bookworm update puts that check in a separate 
patch, which makes it look like an extra fix.

Please let me know if you have any further questions; feedback is still welcome.

Thanks for you quick response.

Indeed, trixie included as:

 From e020c3bb8e04e204b36f9fb56cdcbb6756cd0d28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20G=C3=A9rouville?= <[email protected]>
Date: Thu, 25 Jun 2026 17:22:30 +0200
Subject: [PATCH 7/8] Fix KMREQ buffer overflow at the right place.

but also fixed that check with:

 From 78e7e144bb49b70fc1c20b44e9aa1f5705919e3e Mon Sep 17 00:00:00 2001
From: Mikolaj Malecki <[email protected]>
Date: Thu, 25 Jun 2026 18:19:49 +0200
Subject: [PATCH 8/8] [core] Fixed response for rogue KMREQ message


Could you please double check that?
Thanks for catching that. I focused on whether the length check was present and 
missed that the next commit also changed how a failed check is handled. I 
should have followed it through to the end of the patch rather than stopping 
once I found the check.

I've updated the Bookworm patch to handle that failure the same way as Trixie, 
leaving out the parts that don't apply to this older version, and 
rebuilt/retested, with success. The new debdiff is attached. I've pushed it to 
Salsa and to Debusine.

Here is my Salsa fork: https://salsa.debian.org/tsimonq2/libsrt/-/tree/bookworm

Here is the Debusine work request: 
https://debusine.debian.net/debian/developers/work-request/1601134/

Feedback is still welcome. I'll wait until tomorrow afternoon instead of 
uploading it in the morning, to allow for about 24 hours in case there is 
additional feedback here.

Best regards,
Simon Quigley
[email protected]
diff -Nru srt-1.5.1/debian/changelog srt-1.5.1/debian/changelog
--- srt-1.5.1/debian/changelog  2024-11-08 08:09:06.000000000 -0600
+++ srt-1.5.1/debian/changelog  2026-11-09 15:21:13.000000000 -0600
@@ -1,3 +1,11 @@
+srt (1.5.1-1+deb12u2) bookworm-security; urgency=high
+
+  * Non-maintainer upload by the LTS Team.
+  * CVE-2026-55869: Reject an oversized KMREQ or KMRSP before the stack copy.
+  * CVE-2026-55868: Ignore a forged key refresh on a secured session.
+
+ -- Simon Quigley <[email protected]>  Mon, 09 Nov 2026 15:21:13 -0600
+
 srt (1.5.1-1+deb12u1) bookworm; urgency=medium
 
   * [1e9db13] d/control: correct hard dependencies for dev packages.
diff -Nru srt-1.5.1/debian/patches/CVE-2026-55868-d17cc7b4.patch 
srt-1.5.1/debian/patches/CVE-2026-55868-d17cc7b4.patch
--- srt-1.5.1/debian/patches/CVE-2026-55868-d17cc7b4.patch      1969-12-31 
18:00:00.000000000 -0600
+++ srt-1.5.1/debian/patches/CVE-2026-55868-d17cc7b4.patch      2026-11-09 
15:21:09.000000000 -0600
@@ -0,0 +1,323 @@
+Origin: backport, 
https://github.com/Haivision/srt/commit/d17cc7b4dbe4658eb3ac71c7eec3c71780553250
+Origin: backport, 
https://github.com/Haivision/srt/commit/e02c8b0785e2771103003fa16fe8a2033ff19605
+Origin: backport, 
https://github.com/Haivision/srt/commit/80d7f419360e5ec620f77da43c9333daacfd4df5
+Origin: backport, 
https://github.com/Haivision/srt/commit/78e7e144bb49b70fc1c20b44e9aa1f5705919e3e
+Reviewed-by: Simon Quigley <[email protected]>
+Last-Update: 2026-11-09
+
+Backported to 1.5.1. Net of d17cc7b4,
+e02c8b0785e2771103003fa16fe8a2033ff19605 (restore the previous KEK
+when unwrap fails), 80d7f419360e5ec620f77da43c9333daacfd4df5 (one
+failure state), and 78e7e144bb49b70fc1c20b44e9aa1f5705919e3e (a failed
+refresh sends no KMRSP, and an oversized KMREQ takes that same
+path). 15a7c6f79af572b84740745339deb0cfbd881c58 removed a key-index
+check that d17cc7b4 had added; that check is not included. 1.5.1 has
+no AES-GCM.
+
+From d17cc7b4dbe4658eb3ac71c7eec3c71780553250 Mon Sep 17 00:00:00 2001
+From: Mikolaj Malecki <[email protected]>
+Date: Fri, 5 Jun 2026 14:09:18 +0200
+Subject: [PATCH] Mimimum patch to fix spoofed MKREQ failure
+
+
+--- a/srtcore/crypto.cpp
++++ b/srtcore/crypto.cpp
+@@ -131,34 +131,32 @@ int srt::CCryptoControl::processSrtMsg_K
+      * Re-swap to cancel it.
+      */
+ #ifdef SRT_ENABLE_ENCRYPTION
++    const bool bidirectional = hsv > CUDT::HS_VERSION_UDT4;
++    // A context already exists once the first KMREQ has been accepted.
++    // A later KMREQ is a key refresh. Failure on that path must not move
++    // an established SECURED receiver to BADSECRET.
++    const bool kmx_update = m_hRcvCrypto;
++    SRT_KM_STATE failure_state = m_KmSecret.len == 0 ? SRT_KM_S_NOSECRET : 
SRT_KM_S_BADSECRET;
++
++    int rc = HAICRYPT_OK;
++    size_t sek_len = 0;
++    unsigned char* kmdata;
++
+     // Reject before HtoNLA. The caller passes a stack buffer of 
SRTDATA_MAXSIZE
+     // words (processSrtMsg), and an oversized or misaligned KMREQ writes 
past it.
+     if (bytelen % sizeof(uint32_t) != 0 || bytelen > HCRYPT_MSG_KM_MAX_SZ)
+     {
+         LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: size of the KM (" << 
bytelen << ") is too high, must be < " << HCRYPT_MSG_KM_MAX_SZ);
+-        return SRT_CMD_NONE;
++        goto HSv4_ErrorReport;
+     }
+     w_srtlen = bytelen/sizeof(srtdata[SRT_KMR_KMSTATE]);
+     HtoNLA((pw_srtdata_out), srtdata, w_srtlen);
+-    unsigned char* kmdata = reinterpret_cast<unsigned char*>(pw_srtdata_out);
++    kmdata = reinterpret_cast<unsigned char*>(pw_srtdata_out);
+ 
+     // The side that has received KMREQ is always an HSD_RESPONDER, 
regardless of
+     // what has called this function. The HSv5 handshake only enforces 
bidirectional
+     // connection.
+ 
+-    bool bidirectional = hsv > CUDT::HS_VERSION_UDT4;
+-
+-    // Local macro to return rejection appropriately.
+-    // CHANGED. The first version made HSv5 reject the connection.
+-    // This isn't well handled by applications, so the connection is
+-    // still established, but unable to handle any transport.
+-//#define KMREQ_RESULT_REJECTION() if (bidirectional) { return SRT_CMD_NONE; 
} else { w_srtlen = 1; goto HSv4_ErrorReport; }
+-#define KMREQ_RESULT_REJECTION() { w_srtlen = 1; goto HSv4_ErrorReport; }
+-
+-    int rc = HAICRYPT_OK; // needed before 'goto' run from 
KMREQ_RESULT_REJECTION macro
+-    bool wasb4 SRT_ATR_UNUSED = false;
+-    size_t sek_len = 0;
+-
+     // What we have to do:
+     // If encryption is on (we know that by having m_KmSecret nonempty), 
create
+     // the crypto context (if bidirectional, create for both sending and 
receiving).
+@@ -169,8 +167,7 @@ int srt::CCryptoControl::processSrtMsg_K
+     if ( bytelen <= HCRYPT_MSG_KM_OFS_SALT )  //Sanity on message
+     {
+         LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: size of the KM (" << 
bytelen << ") is too small, must be >" << HCRYPT_MSG_KM_OFS_SALT);
+-        m_RcvKmState = SRT_KM_S_BADSECRET;
+-        KMREQ_RESULT_REJECTION();
++        goto HSv4_ErrorReport;
+     }
+ 
+     HLOGC(cnlog.Debug, log << "KMREQ: getting SEK and creating receiver 
crypto");
+@@ -178,8 +175,13 @@ int srt::CCryptoControl::processSrtMsg_K
+     if ( sek_len == 0 )
+     {
+         LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: Received SEK is empty 
- REJECTING!");
+-        m_RcvKmState = SRT_KM_S_BADSECRET;
+-        KMREQ_RESULT_REJECTION();
++        goto HSv4_ErrorReport;
++    }
++
++    if (kmx_update && m_iRcvKmKeyLen != sek_len)
++    {
++        LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: KMX refresh came in 
with a DIFFERENT KEY LEN: " << sek_len);
++        goto HSv4_ErrorReport;
+     }
+ 
+     // Write the key length
+@@ -201,59 +203,59 @@ int srt::CCryptoControl::processSrtMsg_K
+     if (m_KmSecret.len == 0)  //We have a shared secret <==> encryption is on
+     {
+         LOGC(cnlog.Warn, log << "processSrtMsg_KMREQ: Agent does not declare 
encryption - won't decrypt incoming packets!");
+-        m_RcvKmState = SRT_KM_S_NOSECRET;
+-        KMREQ_RESULT_REJECTION();
++        failure_state = SRT_KM_S_NOSECRET;
++        goto HSv4_ErrorReport;
+     }
+-    wasb4 = m_hRcvCrypto;
+ 
+     if (!createCryptoCtx(m_iRcvKmKeyLen, HAICRYPT_CRYPTO_DIR_RX, 
(m_hRcvCrypto)))
+     {
+         LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: Can't create RCV 
CRYPTO CTX - must reject...");
+-        m_RcvKmState = SRT_KM_S_NOSECRET;
+-        KMREQ_RESULT_REJECTION();
++        failure_state = SRT_KM_S_NOSECRET;
++        goto HSv4_ErrorReport;
+     }
+ 
+-    if (!wasb4)
++    if (!kmx_update)
+     {
+         HLOGC(cnlog.Debug, log << "processSrtMsg_KMREQ: created RX ENC with 
KeyLen=" << m_iRcvKmKeyLen);
++        // We have both sides set with password, so both are pending for 
security.
++        // Do this only for the first KMREQ. A refresh must stay SECURED until
++        // the new key is actually installed.
++        m_RcvKmState = SRT_KM_S_SECURING;
+     }
+-    // We have both sides set with password, so both are pending for security
+-    m_RcvKmState = SRT_KM_S_SECURING;
+-    // m_SndKmState is set to SECURING or UNSECURED in init(),
+-    // or it might have been set to SECURED, NOSECRET or BADSECRET in the 
previous
+-    // handshake iteration (handshakes may be sent multiple times for the 
same connection).
+ 
+     rc = HaiCrypt_Rx_Process(m_hRcvCrypto, kmdata, bytelen, NULL, NULL, 0);
+-    switch(rc >= 0 ? HAICRYPT_OK : rc)
+-    {
+-    case HAICRYPT_OK:
+-        m_RcvKmState = SRT_KM_S_SECURED;
+-        HLOGC(cnlog.Debug, log << "KMREQ/rcv: (snd) Rx process successful - 
SECURED.");
+-        //Send back the whole message to confirm
+-        break;
+-    case HAICRYPT_ERROR_WRONG_SECRET: //Unmatched shared secret to decrypt 
wrapped key
+-        m_RcvKmState = m_SndKmState = SRT_KM_S_BADSECRET;
+-        //Send status KMRSP message to tel error
+-        w_srtlen = 1;
+-        LOGC(cnlog.Warn, log << "KMREQ/rcv: (snd) Rx process failure - 
BADSECRET");
+-        break;
+-    case HAICRYPT_ERROR: //Other errors
+-    default:
+-        m_RcvKmState = m_SndKmState = SRT_KM_S_NOSECRET;
+-        w_srtlen = 1;
+-        LOGC(cnlog.Warn, log << "KMREQ/rcv: (snd) Rx process failure (IPE) - 
NOSECRET");
+-        break;
+-    }
+-
+-    LOGP(cnlog.Note, FormatKmMessage("processSrtMsg_KMREQ", SRT_CMD_KMREQ, 
bytelen));
+ 
+     // Since now, when CCryptoControl::decrypt() encounters an error, it will 
print it, ONCE,
+     // until the next KMREQ is received as a key regeneration.
+     m_bErrorReported = false;
+ 
++    if (rc >= 0)
++    {
++        m_RcvKmState = SRT_KM_S_SECURED;
++        HLOGC(cnlog.Debug, log << "KMREQ/rcv: (snd) Rx process successful - 
SECURED.");
++        //Send back the whole message to confirm
++    }
++    else
++    {
++        switch (rc)
++        {
++        case HAICRYPT_ERROR_WRONG_SECRET: //Unmatched shared secret to 
decrypt wrapped key
++            failure_state = SRT_KM_S_BADSECRET;
++            LOGC(cnlog.Warn, log << "KMREQ/rcv: (snd) Rx process failure - 
BADSECRET");
++            break;
++        case HAICRYPT_ERROR: //Other errors
++        default:
++            failure_state = SRT_KM_S_NOSECRET;
++            LOGC(cnlog.Warn, log << "KMREQ/rcv: (snd) Rx process failure 
(IPE) - NOSECRET");
++            break;
++        }
+ 
+-    if (w_srtlen == 1)
++        if (!kmx_update)
++            m_SndKmState = failure_state;
+         goto HSv4_ErrorReport;
++    }
++
++    LOGP(cnlog.Note, FormatKmMessage("processSrtMsg_KMREQ", SRT_CMD_KMREQ, 
bytelen));
+ 
+     // Configure the sender context also, if it succeeded to configure the
+     // receiver context and we are using bidirectional mode.
+@@ -311,6 +313,13 @@ int srt::CCryptoControl::processSrtMsg_K
+ 
+ HSv4_ErrorReport:
+ 
++    // A refresh of an existing association must leave the current state
++    // alone. Returning no KMRSP matters: announcing BADSECRET is how a
++    // forged KMREQ used to make the receiver take unencrypted packets.
++    if (kmx_update)
++        return SRT_CMD_NONE;
++
++    m_RcvKmState = failure_state;
+     if (bidirectional && hasPassphrase())
+     {
+         // If the Forward KMX process has failed, the reverse-KMX process was 
not done at all.
+@@ -319,7 +328,6 @@ HSv4_ErrorReport:
+         // Create the "fake crypto" with the passphrsae you currently have.
+         createFakeSndContext();
+     }
+-#undef KMREQ_RESULT_REJECTION
+ 
+ #else
+     // It's ok that this is reported as error because this happens in a 
scenario,
+--- a/haicrypt/hcrypt_ctx_rx.c
++++ b/haicrypt/hcrypt_ctx_rx.c
+@@ -128,19 +128,22 @@ int hcryptCtx_Rx_ParseKM(hcrypt_Session
+               return(-1);
+       }
+ 
++      /* Apply salt, SEK length, and KEK on a copy. Commit only after unwrap
++       * succeeds, so a forged KMREQ cannot replace the keys of a secured 
session. */
++      hcrypt_Ctx new_ctx = *ctx;
+       /* Check Salt and get if new */
+-      if ((salt_len != ctx->salt_len)
+-      ||  (0 != memcmp(ctx->salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], 
salt_len))) {
++      if ((salt_len != new_ctx.salt_len)
++      ||  (0 != memcmp(new_ctx.salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], 
salt_len))) {
+               /* Salt changed (or 1st KMmsg received) */
+-              memcpy(ctx->salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], salt_len);
+-              ctx->salt_len = salt_len;
++              memcpy(new_ctx.salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], salt_len);
++              new_ctx.salt_len = salt_len;
+               do_pbkdf = 1; /* Impact on password derived kek */
+       }
+ 
+       /* Check SEK length and get if new */
+-      if (sek_len != ctx->sek_len) {
++      if (sek_len != new_ctx.sek_len) {
+               /* Key length changed or 1st KMmsg received */
+-              ctx->sek_len = sek_len;
++              new_ctx.sek_len = sek_len;
+               do_pbkdf = 1; /* Impact on password derived kek */
+       }
+ 
+@@ -148,21 +151,32 @@ int hcryptCtx_Rx_ParseKM(hcrypt_Session
+        * Regenerate KEK if it is password derived
+        * and Salt or SEK length changed
+        */
+-      if (ctx->cfg.pwd_len && do_pbkdf) {
+-              if (hcryptCtx_GenSecret(crypto, ctx)) {
++      int rollback_kek = 0;
++      if (new_ctx.cfg.pwd_len && do_pbkdf) {
++              if (hcryptCtx_GenSecret(crypto, &new_ctx)) {
+                       return(-1);
+               }
+-              ctx->status = HCRYPT_CTX_S_SARDY;
++              new_ctx.status = HCRYPT_CTX_S_SARDY;
+               kek_len = sek_len;      /* KEK changed */
++              rollback_kek = 1;
+       }
+ 
+       /* Unwrap SEK(s) and set in context */
+-      if (0 > crypto->cryspr->km_unwrap(crypto->cryspr_cb, seks,
+-              &km_msg[HCRYPT_MSG_KM_OFS_SALT + salt_len], 
+-              (sek_cnt * sek_len) + HAICRYPT_WRAPKEY_SIGN_SZ)) {
+-              HCRYPT_LOG(LOG_WARNING, "%s", "unwrap key failed\n");
+-              return(-2); //Report unmatched shared secret
++      {
++              unsigned int msglen = (sek_cnt * sek_len) + 
HAICRYPT_WRAPKEY_SIGN_SZ;
++              int wrc = crypto->cryspr->km_unwrap(crypto->cryspr_cb, seks,
++                      &km_msg[HCRYPT_MSG_KM_OFS_SALT + salt_len],
++                      msglen);
++              if (wrc < 0) {
++                      HCRYPT_LOG(LOG_WARNING, "%s%s\n", "unwrap key failed - 
internal KEK: ", rollback_kek ? "ROLLBACK" : "unchanged");
++                      /* GenSecret installs the KEK into the session. On 
failure, put the
++                       * previous KEK back. The live context itself was not 
modified. */
++                      if (rollback_kek)
++                              hcryptCtx_GenSecret(crypto, ctx);
++                      return(-2); //Report unmatched shared secret
++              }
+       }
++      *ctx = new_ctx;
+       /*
+        * First SEK in KMmsg is eSEK if both SEK present
+        */
+--- a/haicrypt/hcrypt_rx.c
++++ b/haicrypt/hcrypt_rx.c
+@@ -99,6 +99,11 @@ int HaiCrypt_Rx_Process(HaiCrypt_Handle
+                       HCRYPT_LOG(LOG_ERR, "%s", "cryspr had no decryptor\n");
+                       nbout = -1;
+               } else if (ctx->status >= HCRYPT_CTX_S_KEYED) {
++                      if ((int)in_len <= crypto->msg_info->pfx_len)
++                      {
++                              HCRYPT_LOG(LOG_ERR, "%s%d", "Invalid enc data 
packet: ", (int)in_len);
++                              return -1;
++                      }
+                       hcrypt_DataDesc indata;
+                       indata.pfx      = in_msg;
+                       indata.payload  = &in_msg[crypto->msg_info->pfx_len];
+--- a/srtcore/core.cpp
++++ b/srtcore/core.cpp
+@@ -10145,6 +10145,20 @@ int srt::CUDT::processData(CUnit* in_uni
+                 }
+             }
+ 
++            // An encrypted session (anything but UNSECURED) must not accept a
++            // clear packet. A forged KMREQ used to move SECURED to BADSECRET,
++            // after which a clear packet was stored and delivered.
++            if (u->m_Packet.getMsgCryptoFlags() == EK_NOENC
++                && m_pCryptoControl
++                && m_pCryptoControl->m_RcvKmState != SRT_KM_S_UNSECURED)
++            {
++                HLOGC(qrlog.Debug, log << CONID() << "Packet not encrypted, 
dropping data.");
++                IF_HEAVY_LOGGING(exc_type = "UNENCRYPTED");
++                ScopedLock lg(m_StatsLock);
++                m_stats.rcvr.undecrypted.count(stats::BytesPackets(pktsz, 1));
++                continue;
++            }
++
+             bool adding_successful = true;
+ #if ENABLE_NEW_RCVBUFFER
+             if (m_pRcvBuffer->insert(u) < 0)
diff -Nru srt-1.5.1/debian/patches/CVE-2026-55869-05708112.patch 
srt-1.5.1/debian/patches/CVE-2026-55869-05708112.patch
--- srt-1.5.1/debian/patches/CVE-2026-55869-05708112.patch      1969-12-31 
18:00:00.000000000 -0600
+++ srt-1.5.1/debian/patches/CVE-2026-55869-05708112.patch      2026-11-09 
15:21:09.000000000 -0600
@@ -0,0 +1,39 @@
+Origin: backport, 
https://github.com/Haivision/srt/commit/0570811260a9d1e353c4ec85218fe65ab6bd2644
+Reviewed-by: Simon Quigley <[email protected]>
+Last-Update: 2026-11-05
+
+Backported to 1.5.1. The length check is unchanged. 1.5.1 has no
+test/test_crypto.cpp, so the unit test from this commit is not included.
+processSrtMsg_KMRSP still takes the handshake version as its third argument.
+
+From 0570811260a9d1e353c4ec85218fe65ab6bd2644 Mon Sep 17 00:00:00 2001
+From: Matthew Szatmary <[email protected]>
+Date: Fri, 15 May 2026 14:17:27 -0700
+Subject: [PATCH] [BUG] Validate KMRSP wire length to prevent stack overflow
+
+
+diff --git a/srtcore/crypto.cpp b/srtcore/crypto.cpp
+index 4740102..8703d0b 100644
+--- a/srtcore/crypto.cpp
++++ b/srtcore/crypto.cpp
+@@ -330,6 +330,20 @@ HSv4_ErrorReport:
+ 
+ int srt::CCryptoControl::processSrtMsg_KMRSP(const uint32_t* srtdata, size_t 
len, int /* XXX unused? hsv*/)
+ {
++    // Validate the wire-supplied length before using it:
++    //  - oversize would overflow the fixed-size stack buffer below;
++    //  - non-word-aligned or too-small payloads are malformed by protocol 
and would
++    //    feed uninitialised stack into downstream key-matching logic.
++    if (len > SRT_CMD_MAXSZ
++        || len < sizeof(uint32_t)
++        || (len % sizeof(uint32_t)) != 0)
++    {
++        LOGC(cnlog.Error, log << "processSrtMsg_KMRSP: malformed len " << len
++                              << " (must be a non-zero multiple of " << 
sizeof(uint32_t)
++                              << ", up to " << SRT_CMD_MAXSZ << ") - 
rejecting");
++        return SRT_CMD_NONE;
++    }
++
+     /* All 32-bit msg fields (if present) swapped on reception
+      * But HaiCrypt expect network order message
+      * Re-swap to cancel it.
diff -Nru srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch 
srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch
--- srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch      1969-12-31 
18:00:00.000000000 -0600
+++ srt-1.5.1/debian/patches/CVE-2026-55869-e020c3bb.patch      2026-11-09 
15:21:09.000000000 -0600
@@ -0,0 +1,31 @@
+Origin: backport, 
https://github.com/Haivision/srt/commit/e020c3bb8e04e204b36f9fb56cdcbb6756cd0d28
+Reviewed-by: Simon Quigley <[email protected]>
+Last-Update: 2026-11-05
+
+Backported to 1.5.1. The check rejects the KMREQ before HtoNLA copies it
+into the caller's fixed stack buffer.
+
+From e020c3bb8e04e204b36f9fb56cdcbb6756cd0d28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Cl=C3=A9ment=20G=C3=A9rouville?= <[email protected]>
+Date: Thu, 25 Jun 2026 17:22:30 +0200
+Subject: [PATCH] Fix KMREQ buffer overflow at the right place.
+
+
+diff --git a/srtcore/crypto.cpp b/srtcore/crypto.cpp
+index 4740102..8703d0b 100644
+--- a/srtcore/crypto.cpp
++++ b/srtcore/crypto.cpp
+@@ -131,6 +131,13 @@ int srt::CCryptoControl::processSrtMsg_KMREQ(
+      * Re-swap to cancel it.
+      */
+ #ifdef SRT_ENABLE_ENCRYPTION
++    // Reject before HtoNLA. The caller passes a stack buffer of 
SRTDATA_MAXSIZE
++    // words (processSrtMsg), and an oversized or misaligned KMREQ writes 
past it.
++    if (bytelen % sizeof(uint32_t) != 0 || bytelen > HCRYPT_MSG_KM_MAX_SZ)
++    {
++        LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: size of the KM (" << 
bytelen << ") is too high, must be < " << HCRYPT_MSG_KM_MAX_SZ);
++        return SRT_CMD_NONE;
++    }
+     w_srtlen = bytelen/sizeof(srtdata[SRT_KMR_KMSTATE]);
+     HtoNLA((pw_srtdata_out), srtdata, w_srtlen);
+     unsigned char* kmdata = reinterpret_cast<unsigned char*>(pw_srtdata_out);
diff -Nru srt-1.5.1/debian/patches/series srt-1.5.1/debian/patches/series
--- srt-1.5.1/debian/patches/series     2022-07-02 04:10:44.000000000 -0500
+++ srt-1.5.1/debian/patches/series     2026-11-06 09:52:27.000000000 -0600
@@ -1,2 +1,5 @@
 001-multiarch-rpath.patch
 test_failures.patch
+CVE-2026-55869-05708112.patch
+CVE-2026-55869-e020c3bb.patch
+CVE-2026-55868-d17cc7b4.patch

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to