]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Orphan packets from qrx
authorNeil Horman <nhorman@openssl.org>
Fri, 7 Mar 2025 21:35:47 +0000 (16:35 -0500)
committerAlexandr Nedvedicky <sashan@openssl.org>
Sun, 9 Mar 2025 17:44:53 +0000 (18:44 +0100)
It may occur that the qrx we allocate in port_default_packet handler to
do AEAD validation isn't the one the channel ultimately uses (like if we
turn off address validation).  In that event, we need to ensure that
anything we have on that qrx isn't returned to its free list to avoid
early freeing when we free the qrx at the end of
port_default_packet_handler, while those frames are still pending on the
channel qrx

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27004)

include/internal/quic_record_rx.h
ssl/quic/quic_record_rx.c

index 8db7f3fc0dcc429dc0ca0009d5fd91cd0d1195d2..27ac309b300b9b81dd99beb9780351f8366031ea 100644 (file)
@@ -259,6 +259,12 @@ int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **pkt);
  */
 void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt);
 
+/*
+ * Like ossl_qrx_pkt_release, but just ensures that the refcount is dropped
+ * on this qrx_pkt, and ensure its not on any list
+ */
+void ossl_qrx_pkt_orphan(OSSL_QRX_PKT *pkt);
+
 /* Increments the reference count for the given packet. */
 void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt);
 
index 29625118ae474475480472bec2ee36576381aa42..e4ee26c9d1087d118f5caecc8e71380306503c10 100644 (file)
@@ -279,7 +279,7 @@ void ossl_qrx_inject_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT *pkt)
      * port_default_packet_handler() uses ossl_qrx_read_pkt()
      * to get pkt. Such packet has refcount 1.
      */
-    ossl_qrx_pkt_release(pkt);
+    ossl_qrx_pkt_orphan(pkt);
     if (ossl_assert(rxe->refcount == 0))
         ossl_list_rxe_insert_tail(&qrx->rx_pending, rxe);
 }
@@ -1473,6 +1473,19 @@ void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt)
         qrx_recycle_rxe(pkt->qrx, rxe);
 }
 
+void ossl_qrx_pkt_orphan(OSSL_QRX_PKT *pkt)
+{
+    RXE *rxe;
+
+    if (pkt == NULL)
+        return;
+    rxe = (RXE *)pkt;
+    assert(rxe->refcount > 0);
+    rxe->refcount--;
+    assert(ossl_list_rxe_prev(rxe) == NULL && ossl_list_rxe_next(rxe) == NULL);
+    return;
+}
+
 void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt)
 {
     RXE *rxe = (RXE *)pkt;