Debian Patches

Status for openssl/3.5.7-1~deb13u3

Patch Description Author Forwarded Bugs Origin Last update
ssl-record-methods-dtls_meth.c-lower-the-unprocessed_rcds.patch ssl/record/methods/dtls_meth.c: lower the unprocessed_rcds queue limit

100 buffered next-epoch records is far more than a normal handshake
ever needs. A peer that has already completed its side of the epoch
transition may send more than one record under the new epoch before
we catch up and bump our own receive epoch - for example, application
data sent immediately once the peer considers the handshake done -
but real-world bursts like that are still small. Now that each entry
only costs as much memory as the record actually received, the limit
mainly serves as a ceiling on worst-case per-connection memory use, so
lower it to 16 to keep that ceiling smaller while still leaving ample
headroom over legitimate usage.
Matt Caswell <matt@openssl.foundation> no 2026-06-23
ssl-record-remove-dead-DTLS-processed_rcds-record-queue.patch ssl/record: remove dead DTLS processed_rcds record queue
rl->processed_rcds and the functions that serviced it
(dtls_copy_rlayer_record(), dtls_retrieve_rlayer_buffered_record())
were unreachable: nothing in the codebase ever inserted a record into
that queue, so the only consumer of it - the check at the top of
dtls_get_more_records() - always saw an empty queue. The real
mechanism for handing buffered next-epoch records to the next epoch's
record layer is the unrelated forwarding code in dtls_free(), which
pushes the raw bytes from rl->unprocessed_rcds onto rl->next.
Matt Caswell <matt@openssl.foundation> no 2026-06-23
CMP-unexpected-sender-DN-used-as-format-string-in-ERR_rai.patch CMP unexpected sender DN used as format string in ERR_raise_data()
ossl_cmp_msg_check_update() converts an unexpected CMP response sender DN with
X509_NAME_oneline() and passes that peer-controlled string directly as the
format argument to ERR_raise_data(). Printable percent characters survive the
DN conversion, so a sender such as CN=%s%n reaches vsnprintf() as active format
syntax without matching varargs.


Original patch by: Filipe Casal of Trail of Bits in collaboration with OpenAI
Norbert Pocs <norbertp@openssl.org> no 2026-07-20
debian-targets.patch debian-targets Debian OpenSSL Team <pkg-openssl-devel@lists.alioth.debian.org> no 2017-11-05
man-section.patch man-section Debian OpenSSL Team <pkg-openssl-devel@lists.alioth.debian.org> no 2017-11-05
no-symbolic.patch no-symbolic Debian OpenSSL Team <pkg-openssl-devel@lists.alioth.debian.org> no 2017-11-05
pic.patch pic Debian OpenSSL Team <pkg-openssl-devel@lists.alioth.debian.org> no 2017-11-05
c_rehash-compat.patch also create old hash for compatibility Ludwig Nussel <ludwig.nussel@suse.de> no 2010-04-21
Configure-allow-to-enable-ktls-if-target-does-not-start-w.patch Configure: allow to enable ktls if target does not start with Linux
The Debian build system uses a `debian' target which sets CFLAGS and
then we have for instance debian-amd64 which inherits from
linux-x86_64 and debian. So far so good.

Since the target name does not start with `linux', the build system does not
enable ktls. So in order to get enabled, I
added a
`enable => [ "ktls" ],'
to the generic linux config which sets it explicit). Having this set, we can
check for it instead matching the target name.

This commit is based on changes for afalgeng in commit
9e381e8a01859 ("Configure: allow to enable afalgeng if target does not start with Linux")
Sebastian Andrzej Siewior <sebastian@breakpoint.cc> no 2021-04-01
conf-Serialize-allocation-free-of-ssl_names.patch conf: Serialize allocation/free of ssl_names.
The access to `ssl_names' is not fully serialized. With multiple threads
it is possible that more than one thread starts to clean up `ssl_names'.
This leads to occasional segfaults if more than one terminates and
performs the clean up.
Sebastian Andrzej Siewior <sebastian@breakpoint.cc> no 2022-09-19
Add-test-for-CVE-2026-63073.patch Add test for CVE-2026-63073 Norbert Pocs <norbertp@openssl.org> no 2026-07-22
Add-a-test-for-restricting-growth-in-cmp-cert-cache.patch Add a test for restricting growth in cmp cert cache
Test to ensure that if certs are rejected we don't add them unboundedly
to the cmp contexts cert cache.
Neil Horman <nhorman@openssl.org> no 2026-06-30
Avoid-double-free-of-qrx-in-port_default_packet_handler.patch Avoid double free of qrx in port_default_packet_handler()
port_default_packet_handler() may perform double free of qrx
when channel creation fails. The port_default_packet_handler()
transfers ownership of qrx to channel/connection via call to
port_bind_channel(). The port_bind_channel() however may
release the qrx when channel can not be bound. The error is
then detected in port_default_packet_handler() which then agains
releases qrx for the second time.

The fix is to add a reference counter to QRX object so transfer
of ownership between port_default_packet_handler() and QUIC_CHANNEL
can be handled safely.

Fixes CVE-2026-18798
Alexandr Nedvedicky <sashan@openssl.org> no 2026-08-05
Add-test-for-CVE-2026-63072.patch Add test for CVE-2026-63072 Daniel Kubec <kubec@openssl.foundation> no 2026-07-23
Fix-heap-buffer-overflow-8-byte-OOB-write-in-AES-WRAP-PAD.patch Fix heap buffer overflow (8-byte OOB write) in AES-WRAP-PAD unwrap
On its integrity-failure paths that primitive writes and cleanses up to inlen
bytes of the output buffer. Size the buffer for that worst case so a failed
unwrap cannot write past the allocation.

Fixes CVE-2026-63072
Daniel Kubec <kubec@openssl.foundation> no 2026-08-02
Add-test-for-CVE-2026-63076.patch Add test for CVE-2026-63076 Daniel Kubec <kubec@openssl.foundation> no 2026-07-21
Fix-Remote-NULL-deref-in-ossl_cmp_calc_protection-via-cra.patch Fix Remote NULL deref in ossl_cmp_calc_protection() via crafted protectionAlg

ossl_cmp_calc_protection() only checked whether the protectionAlg parameter
(ppval) was NULL before treating it as a PBMParameter ASN1_STRING.

X509_ALGOR_get0() does not validate the ASN.1 type of the parameter against what
the caller expects. For id-PasswordBasedMAC, a crafted message can encode the
parameter as a BOOLEAN instead of the expected PBMParameter SEQUENCE. Because
the ASN1_TYPE value union overlays the boolean int on the pointer field, ppval
comes back as a bogus non-NULL pointer (e.g. 0xff).

Fixes CVE-2026-63076
Daniel Kubec <kubec@openssl.foundation> no 2026-07-21
Handle-signature_algorithms_cert-extension-in-key-only-co.patch Handle signature_algorithms_cert extension in key-only context
Servers or clients that configure only a private key in
expectation of always negotiating use of RFC7250 raw public keys
failed to handle the "signature_algorithms_cert" extension.

The issue is now resolved and the RPK tests now check that
key-only configurations are robust also when the extension
is sent by the peer.

Key-only configurations are quite uncommon. As a best practice,
RPK-capable servers and clients pair their private key with a
(possibly self-signed) certificate, enabling fallback to X.509
handshakes with non-RPK peers.

Fixes CVE-2026-14457
Viktor Dukhovni <viktor@openssl.org> no 2026-06-27
Avoid-full-read-buffer-allocation-when-buffering-DTLS-nex.patch Avoid full read buffer allocation when buffering DTLS next-epoch records

dtls_rlayer_buffer_record() buffers records that arrive early for the
next epoch while a handshake is in progress. It did this by taking
ownership of the entire live read buffer (sized for the largest
possible record, ~16.7KB) and allocating a brand new one to carry on
reading, regardless of how small the buffered record actually was.
With the queue capped at 100 entries, a peer could send around 100
tiny bogus next-epoch records (~14 bytes each on the wire) and force
around 1.7MB of heap allocation per connection.

Instead, copy only the record's own on-wire bytes (header and
ciphertext) into the queue entry, and leave the live read buffer
untouched. Memory use is now proportional to what the peer actually
sends.

Fixes CVE-2026-54874
Matt Caswell <matt@openssl.foundation> no 2026-06-23
Fix-unbounded-cert-cache-growth-in-cmp.patch Fix unbounded cert cache growth in cmp
If a remote user sends cmp messages to a server with a list of
extraCerts and the message is rejected, the extraCerts from the message
remain in the server contexts untrusted certificate stack. This exposes
servers with long lived ctx objects to denial of service attacks in
which an attacker sends messages intending to be rejected with a large
list of additional cerificated repeatedly, forcing the server to store
them indefinately.

Fix it by rolling back the added extra certs if the message is rejected,
using the same method we do when the context is configured to not do
caching at all.

Fixes openssl/srt#224

Fixes CVE-2026-63074
Neil Horman <nhorman@openssl.org> no 2026-06-30
Don-t-store-ACK-only-frames-in-TX-history-for-QUIC.patch Don't store ACK-only frames in TX history for QUIC.
When QUIC sends an ACK-only frame, there is no expectation that the
peer will ack that ack (i.e. it is itself not ack-eliciting). However,
our implementation stores these frames in the TX history regardless. In and
of itself thats ok, but if a malicious client establishes a connection,
and then drives the connection such that ack-only frames are forced from
the peer (i.e. by sending numerous ping frames), and then withholding
any subseqent acks for ack-eliciting data, like legitimate data, said
malicious client can force inappropriate memory growth on the server,
leading to potential DOS attacks.

Don't store any ACK-only frames in the TX history to address this. Record it in
our TX history so that the send window moves forward appropriately, but for
ack-only frames, immediately remove it, since we don't expect to get an ack for
them anyway.

Initially authored by Opal Wright <opal.wright@trailofbits.com>

The initial proposal had some shortcommings in which the highest pn
acked value was not accounted for which I have fixed with the assistance
of Claude



Original patch by Neil Horman <nhorman@openssl.org>
Norbert Pocs <norbertp@openssl.org> no 2026-08-04
Check-the-tag-on-EVP_Cipher-finalize-Poly1305-and-OCB-AEA.patch Check the tag on EVP_Cipher() finalize: Poly1305 and OCB AEADs
For the affected OpenSSL built-in provider AEAD implementations,
EVP_Cipher(ctx, out, NULL, 0) reaches the ccipher callback as a
NULL-input terminal call. OCB and ChaCha20-Poly1305 took an early exit
on an empty message, with or without AAD, and returned success without
comparing an explicitly supplied tag. Consequently a corrupted tag was
accepted before this change.

Make these built-in callbacks perform their terminal tag operation,
aligning their explicit-tag handling with the streaming Final path
without defining NULL input as part of the generic EVP_Cipher()
contract.

AES-GCM-SIV also failed to generate a tag when Final was its first
empty-message operation. Generate the tag in that case and propagate
failures from the matching empty-message decrypt operation.

The stable ChaCha20-Poly1305 implementation aliases Update to the
one-shot cipher callback, so this backport introduces a dedicated Update
callback to preserve zero-length Update as a no-op.

Follow-up to #31555
Fixes #32258
Fixes CVE-2026-75803


(cherry picked from commit 5741d29a5f356e05262cd0936a472a9961398d53)
Billy Brumley <bbb@iki.fi> no 2026-08-04
QUIC-server-limit-number-of-pending-QUIC-channels-connect.patch QUIC server: limit number of pending QUIC channels/connections
Currently, there is no limit for pending QUIC connections. The port
default packet handler creates channel for every valid initial packet
which does belong to existing channel (a.k.a. connection). The newly
created channel is inserted to list of pending channels where it waits
to be accepted by local application by call
to SSL_accept_connection(3ossl).

This change introduces a limit for pending connection. The pending
queue is limited to 256 pending connections. Applications may change
the limit by calling SSL_set_feature_request_uint(3ossl)
on SSL server listener object with configurable value
SSL_VALUE_QUIC_MAX_PENDING_CONNS.


(Merged from https://github.com/openssl/openssl/pull/32052)

(cherry picked from commit 9416706d408bb84deb7cee4647bff3045d2dc7ba)
(cherry picked from commit 4084152e040329ca0194c4c1750b9b46d00a5b6b)
Alexandr Nedvedicky <sashan@openssl.org> no 2026-07-23
Defer-computation-of-relative-CRLDP-names.patch Defer computation of relative CRLDP names
These are derived just-in-time, during any actual CRL processing.

Fixes CVE-2026-35189
Viktor Dukhovni <viktor@openssl.org> no 2026-09-02
don-t-double-count-full-databgram-length-on-unvalidated-c.patch don't double count full databgram length on unvalidated connections
If a connection is coalescing frames, we pass through
ossl_quic_handle_frames multiple times, each time accounting the full
datagram length to the connection, erroneously amplifying our
unvalidated credit.

Fix it by moving where we account unvalidated credit. If we move the
adding of unvalidated credit to port_default_packet_handler, we can add
the datagram length to the channels unvalidated credit before it gets
broken up into multiple OSSL_QRX_PKT structures.

Fixes CVE-2026-35191
Neil Horman <nhorman@openssl.org> no 2026-08-25
Add-a-test-to-check-for-quic-unvalidated-credit.patch Add a test to check for quic unvalidated credit
Adds a test to ensure that, when sending a coalesced frame that should
drive more than the available unvalidated credit that a server has, we
stop sending when we reach that limit.
Neil Horman <nhorman@openssl.org> no 2026-08-25
fixup-don-t-double-count-full-databgram-length-on-unvalid.patch fixup! don't double count full databgram length on unvalidated connections Neil Horman <nhorman@openssl.org> no 2026-08-28
fixup-Add-a-test-to-check-for-quic-unvalidated-credit.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-08-28
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-1.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-08-28
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-2.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-08-28
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-3.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-08-28
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-4.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-09-10
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-5.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-09-11
fixup-Add-a-test-to-check-for-quic-unvalidated-credit-6.patch fixup! Add a test to check for quic unvalidated credit Neil Horman <nhorman@openssl.org> no 2026-09-14
Make-the-ecp_sm2p256-scalar-multiplication-constant-time.patch Make the ecp_sm2p256 scalar multiplication constant time
Fixes CVE-2026-54875.

This fix implemets the same idea as in PR#30649 by Joshua Rogers (@MegaManSec).
Igor Ustinov <igus@openssl.foundation> no 2026-08-03
Fix-out-of-bounds-valid_flags-access-after-SSL_set_SSL_CT.patch Fix out-of-bounds valid_flags access after SSL_set_SSL_CTX()
SSL_new() sizes the connection-local signature algorithm state from the
SSL_CTX the connection was created from: sc->ssl_pkey_num counts the
built-in certificate slots plus one for each of that context's provider
TLS-SIGALG entries, and s3.tmp.valid_flags is later allocated to match.

SSL_set_SSL_CTX() installs a duplicate of the replacement context's CERT
but leaves both of those describing the original context. Peer signature
algorithm codepoints are subsequently resolved against the replacement
context, where a provider sigalg's sig_idx is simply its position in
that context's list. If the replacement context advertises more provider
sigalgs than the original, a codepoint occupying one of the excess slots
yields an index past the end of valid_flags.

The usual route is a switch from the servername callback, which runs
before tls1_set_server_sigalgs() allocates the buffer: the stale
ssl_pkey_num undersizes the allocation, and tls1_process_sigalgs() then
reads one 4-byte word past the end for each such codepoint the peer
offered, and writes CERT_PKEY_EXPLICIT_SIGN|CERT_PKEY_SIGN where that
word already reads zero. The peer chooses how many of these accesses
occur, and at which offsets, by selecting which codepoints to send.

Refresh ssl_pkey_num from the newly installed CERT and, where a
valid_flags buffer already exists, replace it with one sized for that
context. A count which is too large is wrong in the same way as one that
is too small: loops bounded by ssl_pkey_num index cert->pkeys, which the
replacement context sizes. The replacement buffer is allocated before
the point at which the switch is committed, so that a failure can still
be reported rather than leaving the connection half switched.

The built-in slots are copied across rather than zeroed. They may
already hold peer signature algorithm state which is not derived from
the SSL_CTX, and nothing recomputes it after a context switch: at TLS
1.2 and above tls1_check_chain() only ORs CERT_PKEY_SIGN and
CERT_PKEY_EXPLICIT_SIGN in from the existing value, and ssl_set_masks()
needs them to enable ECDSA, Ed25519 and Ed448. Zeroing them makes a
TLSv1.2 handshake with an ECDSA certificate fail with "no shared
cipher". The provider slots are positional and context specific, so they
are reset.

Fixes CVE-2026-72897
Matt Caswell <matt@openssl.foundation> no 2026-09-08
Add-regression-tests-for-the-SSL_set_SSL_CTX-sigalg-state.patch Add regression tests for the SSL_set_SSL_CTX() sigalg state
The fix for CVE-2026-72897 made SSL_set_SSL_CTX() refresh the
connection's signature algorithm state so that it describes the context
being installed. Cover it.

That state is sized from the SSL_CTX SSL_new() was called on, and a
provider sigalg's sig_idx is its position in the list of whichever
SSL_CTX a peer codepoint is resolved against, so the two have to
describe the same context. The test provider makes them differ: a
context created before it is loaded lacks the two slots it adds, and one
created afterwards has them.

Three routes an application can switch context from are covered, and
they do not behave alike.

test_sigalg_ctx_switch() switches from the servername and client_hello
callbacks, both of which run before tls1_set_server_sigalgs() allocates
valid_flags. A stale slot count undersized that allocation, and
tls1_process_sigalgs() then read and wrote past its end. The two
callbacks run at different points - the client_hello callback before the
ClientHello extensions are parsed at all, the servername callback from
the final pass over them - so they are checked separately. The extra
provider sigalgs are TLSv1.3 only, so only those cases reached past the
end of the buffer; the TLSv1.2 cases pin the invariant.

test_sigalg_ctx_switch_cert_cb() switches from the certificate callback,
which runs after valid_flags has been sized and filled in. Nothing
recomputes the shared sigalgs later in the same handshake, so nothing
read out of bounds on that route, but the state left behind was
inconsistent. It also checks the built-in slots survive the switch,
which is the only coverage of that part of the change.

test_sigalg_ctx_switch_reneg() switches during a TLSv1.2 renegotiation
with a changed servername. valid_flags is allocated by the initial
handshake and not freed in between, so this is the case where the buffer
has to be replaced rather than merely sized correctly later.

Each test checks the premise it depends on rather than risk becoming
the renegotiation really was a full handshake, and that the flags being
compared across the switch were non-zero to begin with.
Matt Caswell <matt@openssl.org> no 2026-09-09
fixup-Fix-out-of-bounds-valid_flags-access-after-SSL_set_.patch fixup! Fix out-of-bounds valid_flags access after SSL_set_SSL_CTX() Matt Caswell <matt@openssl.org> no 2026-09-10
CVE-2026-75804-QUIC-connection-level-flow-control-not-enf.patch CVE-2026-75804 QUIC connection-level flow control not enforced, remote memory exhaustion

Function ossl_quic_rxfc_get_error() must also report flow control violation
error for connection level not just for stream level. Ignoring connection
level error prevents QUIC stack to enforce flow control.

Fixes CVE-2026-75804
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-03
test-verifies-the-connection-level-RX-flow-control.patch test verifies the connection level RX flow control window is enforced. Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-04
Guard-comparision-when-values-are-NULL.patch Guard comparision when values are NULL Norbert Pocs <norbertp@openssl.org> no 2026-08-27
Add-test-for-CVE-2026-75805.patch Add test for CVE-2026-75805 Norbert Pocs <norbertp@openssl.org> no 2026-08-27
TLS-Reject-undersized-TLS-1.2-AEAD-records-before-AEAD-pr.patch TLS: Reject undersized TLS 1.2 AEAD records before AEAD processing
In tls1_cipher() the receive path invoked EVP_CTRL_AEAD_TLS1_AAD before
checking that the record was long enough to contain the mandatory
explicit IV and authentication tag. A record shorter than that overhead
made the provider reject the impossible length, and the error path
raised SSL_AD_INTERNAL_ERROR.

Validate the record length against the explicit IV and tag length before
AEAD processing and return failure without raising an alert, leaving the
caller to react correctly: TLS reports bad_record_mac and DTLS silently
discards the record.


Fixes CVE-2026-75806
Daniel Kubec <kubec@openssl.foundation> no 2026-09-03
ec-make-ossl_ec_scalar_mul_ladder-scalar-padding-constant.patch ec: make ossl_ec_scalar_mul_ladder() scalar padding constant time
Fixes CVE-2026-54872
Igor Ustinov <igus@openssl.foundation> no 2026-07-28
sm2-make-sm2_sig_gen-constant-time.patch sm2: make sm2_sig_gen() constant time
After fixing CVE-2025-9231, sm2_sig_gen() still used variable-time
BN_mod_mul() and BN_sub() on private key and nonce material.
This commit makes it fully constant time.

Fixes CVE-2026-77696
Igor Ustinov <igus@openssl.foundation> no 2026-07-31
dtls-reset-init_off-before-retransmitting-a-message.patch dtls: reset init_off before retransmitting a message
dtls1_retransmit_message() copies a queued message's saved bytes into
s->init_buf and sets s->init_num to its length, but left s->init_off
untouched. If a different message was still mid-write (suspended on
WANT_WRITE, e.g. because the underlying BIO couldn't take any more)
when a retransmit fired, s->init_off would still hold whatever offset
that suspended write had reached - and dtls1_do_write() would resume
the retransmitted message from that stale, unrelated offset instead of
from the start.

The result is a corrupted retransmission: the message goes out
mislabelled with a bogus fragment offset/length, and its body is
whatever bytes happen to sit at that offset in the now-repurposed
init_buf - typically leftover content from the other, larger message
that was mid-write when the retransmit happened, rather than the
message actually meant to be sent.

Fix this by always resetting s->init_off to 0 before resending, so
every retransmit starts from the beginning of the message being sent,
regardless of what any other in-progress write had left behind.

dtls1_handle_timeout() also needs a guard: if write_state is anything
other than WRITE_STATE_TRANSITION, a write is still parked mid-flight
from a previous call into the state machine, so there is nothing valid
to retransmit yet. Retransmitting anyway would reconstruct an
already-sent message from the retransmit queue into
s->init_buf/s->init_off/s->init_num/s->d1->w_msg - the same fields the
parked write is still using - corrupting that write's state out from
under it. Skip retransmission in that case and let the next
SSL_read()/SSL_write()/SSL_accept()/SSL_connect() call resume the
parked write normally instead.

Add test_dtls_client_retransmit() and test_dtls_server_retransmit() to
test/dtlstest.c, covering both directions on DTLS1.2: use a
fragment-limiting BIO to suspend a large in-flight write mid-fragment,
then fire the retransmit timer several times via
DTLSv1_get_timeout()/DTLSv1_handle_timeout() while it stays parked,
verifying no retransmission is attempted and the suspended write's
state is reproduced unchanged on every timer fire, and that resuming
the write afterward completes as an ordinary handshake continuation
instead of hitting dtls1_do_write()'s entry assertion.
Ryan Hooper <ryhooper@cisco.com> no 2026-09-02
CVE-2026-84784-QUIC-unbounded-RETIRE_CONNECTION_ID-backlo.patch CVE-2026-84784 QUIC: unbounded RETIRE_CONNECTION_ID backlog (memory DoS)

Currently the cur_retire_prior_to counter is updated when RETIRE_CONNECTION_ID
is dispatched to control frame queue. However to follow protocol state
at both connection ends the counter must be updated after seeing an ACK
from remote peer indicating it's received RETIRE_CONNECTION_ID frame.

Diverging from protocol spec here allows malicious remote peer to queue
excessive amount of RETIRE_CONNECTION_ID frames to local control
frame queue (CFQ).
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-05
CVE-2026-84784-QUIC-unbounded-RETIRE_CONNECTION_ID-backlo-1.patch CVE-2026-84784 QUIC: unbounded RETIRE_CONNECTION_ID backlog (memory DoS)

connection must fail when remote peer attempts to retire more than
10 connection IDs.

The point is to send more than 10 NEW_CONNECTION_ID frames. Each
frame is retiring earlier connection id.
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-05
Add-a-red-black-tree-implementation.patch Add a red-black tree implementation
The code comes from David Gwynne <david@gwynne.id.au>.
The same implmentation can be found in OpenBSD.

Several minor adjustments have been done to include the code
into OpenSSL:
* the prefix has been changed to OSSL_RBT_,
* the support augment is removed,
* _RBT_CHECK()/_RBT_POISON() got removed too,
* _RB_REMOVE() resets link pointer to NULL in debug build,

The documentation is based on tree(3) from OpenBSD, originally authored
by Niels Provos <provos@openbsd.org>.
Alexandr Nedvedicky <sashan@openssl.org> no 2026-07-21
quic-move-the-RXE-definition-to-a-local-header.patch quic: move the RXE definition to a local header
The RXE structure carries the reference count of a received packet and
embeds the OSSL_QRX_PKT handed out to the users of the QRX as its first
member. It is defined in quic_record_rx.c, so a test that wants to build
a packet without a QRX behind it cannot allocate one or look at its
reference count, and would have to guess the size of the structure and
the offset of the fields it needs.

Move the definition to a local header, following the other local headers
in ssl/quic, so that a test can include it and construct a packet of its
own rather than the library having to provide a constructor for it.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-08-26
test-cover-the-packet-pinning-path-of-QUIC-stream-reassem.patch test: cover the packet pinning path of QUIC stream reassembly
Until now every rstream test queued data with a NULL packet, so the
production path where received chunks pin their OSSL_QRX_PKT via
reference counting was never exercised by any unit test. A NULL packet
is never passed in production, so the tests now always queue data in a
mock packet rather than toggling it.

Have test_rstream_simple and test_rstream_random queue every frame in a
mock packet, and add a new test_rstream_pkt which asserts the reference
counting behaviour directly: references held while chunks are buffered,
shared packets referenced once per frame, references released when frames
are consumed, dropped by overlapping frames, moved to the ring buffer or
freed with the stream, and cleansing of a packet backed chunk wiping
exactly the chunk data.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-08-26
test-cover-a-long-lagging-read-of-packet-backed-stream-da.patch test: cover a long lagging read of packet backed stream data
Queue many small contiguous frames that each pin their own packet while
the reader stays behind, so a large number of packets are held at once and
then released as the data is finally consumed. This exercises the packet
reference lifecycle at a scale the other tests do not reach, and gives a
reassembly that copies data out of packets under memory pressure something
to run against.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-08-26
test-reassemble-small-out-of-order-frames-and-check-the-b.patch test: reassemble small out of order frames and check the bytes
Deliver a buffer as small packet backed frames in a random order with
overlapping retransmits, each carrying its own copy of its bytes, then
read it back and compare. The random order drives insertion at the head,
the tail and the middle of the reassembly, and the frame size is swept
across the boundary where a design may change how it stores a chunk, so
short frames and their overlaps are exercised in every combination with
and without cleanse. It passes on the current implementation and would
catch a reassembly that mishandles any of those.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-08-26
New-implementation-of-stream-reassembly-for-QUIC.patch New implementation of stream reassembly for QUIC.
The new implementation makes clear distinction between stream chunk
and stream range.

The strem chunk is defined by its `start` and `end` offset with
respect to offset 0 (the start of the stream). The `start` < `end`.
The lenght of the stream chunk is `end - start`. The stream chunks
are delivered as QUIC stream frames.

The stream range is list of stream chunks which together create
one continuous range of stream. The range is also deined by
`start` and `end` offset. The ranges are kept in R/B tree.

The chunks which are arriving in order are kept in list which
forms one node of R/B tree. If newly arriving stream chunk
can not be inserted to existing stream range for example because
chunk.start > range.end (there is a gap between existing range and
new chunk), then the new range is created and inserted to R/B
tree.

If the newly arriving chunk closes the gap between two existing
ranges, the ranges are merged to single tree node. The join
proces uses list join operation with O(1) complexity to make
the new continuous range of stream chunks.

In a nutshell: stream reassembly process is R/B tree look up/insert
with tail/head insertion to list.

There is also a preparatory work that will allow us to deal with
memory hog issue. Currently the QUIC stack keeps all stream
frame data on packet buffers until data is moved to application.
On hone hand, this saves one copy opration between on the other
hand it may cause receiver to hold lot more memory than currently
needed. Consider situation where QUIC stack needs to hold reference
to whole packet buffer, just because of sinle 1byte stream chunk.
The 1byte stream chunk (at let's say offset 10) can not be moved
to application yet, because QUIC stack is waiting for data at
offset 0 - 9. Such buffer might be waiting in reassembly queue
for a long time holding a reference to whole packet.

To mitigate this we need to allow the QUIC stack to move data
from packet buffers to stream buffers. The logic which decides
when data should be moved from packet buffers is missing in this
change. Here we just bring the code that supports improved
buffer handling. The data for short stream frames/chunks (16B)
are kept inside the stream chunk structure itself (this is referred
as direct storage, or dstorage). The code coalesces data from adjacent
stream frames into dstorage until it fill up. Once dstorage is full the
new stream chunk is allocated and added to range.

Larger stream chunks (size > 16B) get buffer from the heap.
It is then linked to stream buffer.

This commit just brings the quic_strm_reas.c in. It is not currently
hooked to build.
Alexandr Nedvedicky <sashan@openssl.org> no 2026-08-10
Limit-packet-buffer-overhead-to-64kB-per-stream.patch Limit packet buffer overhead to ~64kB per stream.
There is currently no limit on how many bytes of packet
buffers each stream can hold in memory. To monitor and limit
the size of packet buffers used by stream the change accounts
so called stream chunk overhead which is a delta between
actual datagram size of packet delivering the particular
stream chunk and chunk itself. As soon as the chunk overhead
exceeds ~64kB for all stream chunks kept in receive buffer,
the newly received chunks will be moved from packet buffer
to stream buffer.

The packet buffer overhead limit is held in newly introduced
structure QUIC_RSTREAM_QPARAM (RX stream quality parameter).
If new additional quality parameters are added, then those
should be part of QUIC_RSTREAM_QPARAM structure.

this changeset introduces QUIC_RSTREAM_QPARAM

the the rsqp (reead stream quality parameter) enables
channel to control quality of RX stream. quality currently
means the packet buffer overhead. more parameters
may be added later.
Alexandr Nedvedicky <sashan@openssl.org> no 2026-07-27
Enforce-final-size-for-streams.patch Enforce final size for streams.
When FIN stream frame is received at particular offset,
then the FIN's offset must be the largest offset kept
in stream reassembly buffer.

Receiving stream frame with offset larger than FIN frame
must be reported as protocol violation and connection
must be closed.

In order to report protocol violation error the stream
reassembly module must have a reference to QUIC_CHANNEL
object where particular stream belongs to. The refernce
to channel is part of QUIC_RSTREAM_QPARAM structure.
This change makes stream quality parameter mandatory.
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-09
Add-explicit-tests-to-check-some-typical-stream-reassembl.patch Add explicit tests to check some typical stream reassembly situation
the list of tests is as follows:s
- partial overlap between newly arriving chunk and existing range
(there is intersection between existing range and newly arriving chunk)
- full overlap: existing range is subset of newly arriving stream chunk
- newly arriving chunk is superset of two existing ranges.
- reassembly of 1-byte chunks which are kept in stream buffers
- we need to also test handling of short chunks in directo storage
Alexandr Nedvedicky <sashan@openssl.org> no 2026-08-10
test-cover-FIN-final-size-against-buffered-data.patch test: cover FIN final size against buffered data
A FIN whose final size lies below data already buffered in a higher
range passes the current validation because only the lowest range is
checked, so the frames beyond the final size stay pinned unreadable
until the stream is torn down. A FIN below the offset the application
has consumed already skips the validation entirely when no ranges are
buffered, so it is recorded but can never signal the end of the stream.
Both must be rejected as a final size error per RFC 9000 section 4.5.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-09-07
test-cover-zero-length-read-of-a-QUIC-rstream.patch test: cover zero length read of a QUIC rstream
A zero length read has been a successful no-op returning zero read
bytes, and releasing a record without consuming any bytes succeeded
likewise. The new ossl_sframe_set_move_offset() refuses to keep the
offset in place, so both operations now fail once at least one byte
has been consumed, and quic_read_actual() turns the failed read into
a fatal SSL error for SSL_read_ex() with a zero length buffer.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-09-07
test-cover-two-sided-overlap-of-direct-tail-chunk.patch test: cover two sided overlap of direct tail chunk
A short retransmitted frame which starts below an existing range and
ends past its direct storage tail chunk slips past the full overlap
guard in try_dstorage() because it is not larger than the direct
storage size. The append path then treats every byte below the tail
chunk end as a duplicate and drops the genuinely new bytes below the
range start while reporting success, so the frame is acked and the
gap in the stream becomes permanent.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-09-07
test-cover-cleansing-of-dropped-duplicate-bytes.patch test: cover cleansing of dropped duplicate bytes
With cleansing enabled every dropped duplicate byte of an incoming
frame must be wiped in its packet buffer: a retransmit reaching below
the consumed offset, a retransmit consumed entirely, a duplicate
contained in an existing range and the tail trimmed away when a short
frame is prepended to a direct storage chunk. Otherwise the plaintext
stays in the recycled packet buffer which nothing else cleanses.
Jakub Zelenka <jakub.zelenka@openssl.foundation> no 2026-09-08
test-cover-sc_data_trim_right-function.patch test: cover sc_data_trim_right() function
sc_data_trim_right() function shrinks heap buffer with
stream data by trimming the buffer from its end.
In order to reclaim unused memory the function uses realloc().

To reach code in the sc_data_trim_right() the test queues the fill
frames first so packet buffer overhead tresshold is reached,
The fill frames are intentionally placed beyond the gap so
they don't interfer with testing done later.

The test creates 3 dis-joint ranges. Each range is 64B long.
The offsets are: 0, 128, 256. Then partial read of 16 bytes happens.
After that the test inserts yet another stream frame that carries
160 bytes of data and lands to offset 63. The frame joins the
first two ranges. The join operation calls to sc_data_trim_right().

Finally to verify things do work as expected The test reads
all available data from stream and verifies those data match
the expected content.

The test is based on code submitted by Mounir IDRASSI
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-21
make-ch_cleanup-just-safe-enough-to-be-called-by-quic_str.patch make ch_cleanup() just safe enough to be called by quic_stream_test
quic_stream_test (quic_txp) use dummy channel to perform testing.
the channel object is QUIC_CHANNEL instance allocated by OPENSSL_zalloc()
and released by ossl_quic_channel_free() which calls ch_cleanup()

the ossl_quic_channel_free() assumes the QUIC_CHANNEL is fully
initialized and valid object which is not a case of dummy channel
object created for testing.

this change is specific to openssl 3.4 and 3.5. Newer
OpenSSL versions provide a safe variant of ch_cleanup()
Alexandr Nedvedicky <sashan@openssl.org> no 2026-09-24
Add-ossl_list_TYPE_join-head-tail-function.patch Add ossl_list_TYPE_join(head, tail) function
The function appends list tail to list head. List tail becomes
empty after the function returns.

(Merged from https://github.com/openssl/openssl/pull/32031)
Alexandr Nedvedicky <sashan@openssl.org> no 2026-07-20

All known versions for source package 'openssl'

Links