mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
183 lines
6.3 KiB
C
183 lines
6.3 KiB
C
/* Provenance: openssl/openssl txp_pkt_commit (vuln).
|
|
* repo: openssl/openssl
|
|
* commit: a1f348ccb328c3afbd4ba6883f9b7c813c043259
|
|
* parent: a1f348ccb328c3afbd4ba6883f9b7c813c043259
|
|
* commit_url: https://github.com/openssl/openssl/commit/c902e5f16d6a9e130e96d3ca6d8f64d71652e393
|
|
* cve: CVE-2026-63075
|
|
* license: Apache-2.0
|
|
* function: txp_pkt_commit
|
|
* relpath: ssl/quic/quic_txp.c
|
|
*/
|
|
|
|
static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp,
|
|
struct txp_pkt *pkt,
|
|
uint32_t archetype,
|
|
int *txpim_pkt_reffed)
|
|
{
|
|
int rc = 1;
|
|
uint32_t enc_level = pkt->h.enc_level;
|
|
uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);
|
|
QUIC_TXPIM_PKT *tpkt = pkt->tpkt;
|
|
QUIC_STREAM *stream;
|
|
OSSL_QTX_PKT txpkt;
|
|
struct archetype_data a;
|
|
|
|
*txpim_pkt_reffed = 0;
|
|
|
|
/* Cannot send a packet with an empty payload. */
|
|
if (pkt->h.bytes_appended == 0)
|
|
return 0;
|
|
|
|
if (!txp_get_archetype_data(enc_level, archetype, &a))
|
|
return 0;
|
|
|
|
/* Packet Information for QTX */
|
|
txpkt.hdr = &pkt->phdr;
|
|
txpkt.iovec = txp->el[enc_level].iovec;
|
|
txpkt.num_iovec = pkt->h.num_iovec;
|
|
txpkt.local = NULL;
|
|
txpkt.peer = BIO_ADDR_family(&txp->args.peer) == AF_UNSPEC
|
|
? NULL
|
|
: &txp->args.peer;
|
|
txpkt.pn = txp->next_pn[pn_space];
|
|
txpkt.flags = OSSL_QTX_PKT_FLAG_COALESCE; /* always try to coalesce */
|
|
|
|
/* Generate TXPIM chunks representing STOP_SENDING and RESET_STREAM frames. */
|
|
for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next)
|
|
if (stream->txp_sent_stop_sending || stream->txp_sent_reset_stream) {
|
|
/* Log STOP_SENDING/RESET_STREAM chunk to TXPIM. */
|
|
QUIC_TXPIM_CHUNK chunk;
|
|
|
|
chunk.stream_id = stream->id;
|
|
chunk.start = UINT64_MAX;
|
|
chunk.end = 0;
|
|
chunk.has_fin = 0;
|
|
chunk.has_stop_sending = stream->txp_sent_stop_sending;
|
|
chunk.has_reset_stream = stream->txp_sent_reset_stream;
|
|
if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk))
|
|
return 0; /* alloc error */
|
|
}
|
|
|
|
/* Dispatch to FIFD. */
|
|
if (!ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt))
|
|
return 0;
|
|
|
|
/*
|
|
* Transmission and Post-Packet Generation Bookkeeping
|
|
* ===================================================
|
|
*
|
|
* No backing out anymore - at this point the ACKM has recorded the packet
|
|
* as having been sent, so we need to increment our next PN counter, or
|
|
* the ACKM will complain when we try to record a duplicate packet with
|
|
* the same PN later. At this point actually sending the packet may still
|
|
* fail. In this unlikely event it will simply be handled as though it
|
|
* were a lost packet.
|
|
*/
|
|
++txp->next_pn[pn_space];
|
|
*txpim_pkt_reffed = 1;
|
|
|
|
/* Send the packet. */
|
|
if (!ossl_qtx_write_pkt(txp->args.qtx, &txpkt))
|
|
return 0;
|
|
|
|
/*
|
|
* Record FC and stream abort frames as sent; deactivate streams which no
|
|
* longer have anything to do.
|
|
*/
|
|
for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) {
|
|
if (stream->txp_sent_fc) {
|
|
stream->want_max_stream_data = 0;
|
|
ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 1);
|
|
}
|
|
|
|
if (stream->txp_sent_stop_sending)
|
|
stream->want_stop_sending = 0;
|
|
|
|
if (stream->txp_sent_reset_stream)
|
|
stream->want_reset_stream = 0;
|
|
|
|
if (stream->txp_txfc_new_credit_consumed > 0) {
|
|
if (!ossl_assert(ossl_quic_txfc_consume_credit(&stream->txfc,
|
|
stream->txp_txfc_new_credit_consumed)))
|
|
/*
|
|
* Should not be possible, but we should continue with our
|
|
* bookkeeping as we have already committed the packet to the
|
|
* FIFD. Just change the value we return.
|
|
*/
|
|
rc = 0;
|
|
|
|
stream->txp_txfc_new_credit_consumed = 0;
|
|
}
|
|
|
|
/*
|
|
* If we no longer need to generate any flow control (MAX_STREAM_DATA),
|
|
* STOP_SENDING or RESET_STREAM frames, nor any STREAM frames (because
|
|
* the stream is drained of data or TXFC-blocked), we can mark the
|
|
* stream as inactive.
|
|
*/
|
|
ossl_quic_stream_map_update_state(txp->args.qsm, stream);
|
|
|
|
if (ossl_quic_stream_has_send_buffer(stream)
|
|
&& !ossl_quic_sstream_has_pending(stream->sstream)
|
|
&& ossl_quic_sstream_get_final_size(stream->sstream, NULL))
|
|
/*
|
|
* Transition to DATA_SENT if stream has a final size and we have
|
|
* sent all data.
|
|
*/
|
|
ossl_quic_stream_map_notify_all_data_sent(txp->args.qsm, stream);
|
|
}
|
|
|
|
/* We have now sent the packet, so update state accordingly. */
|
|
if (tpkt->ackm_pkt.is_ack_eliciting)
|
|
txp->force_ack_eliciting &= ~(1UL << pn_space);
|
|
|
|
if (tpkt->had_handshake_done_frame)
|
|
txp->want_handshake_done = 0;
|
|
|
|
if (tpkt->had_max_data_frame) {
|
|
txp->want_max_data = 0;
|
|
ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 1);
|
|
}
|
|
|
|
if (tpkt->had_max_streams_bidi_frame) {
|
|
txp->want_max_streams_bidi = 0;
|
|
ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 1);
|
|
}
|
|
|
|
if (tpkt->had_max_streams_uni_frame) {
|
|
txp->want_max_streams_uni = 0;
|
|
ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 1);
|
|
}
|
|
|
|
if (tpkt->had_ack_frame)
|
|
txp->want_ack &= ~(1UL << pn_space);
|
|
|
|
if (tpkt->had_conn_close)
|
|
txp->want_conn_close = 0;
|
|
|
|
/*
|
|
* Decrement probe request counts if we have sent a packet that meets
|
|
* the requirement of a probe, namely being ACK-eliciting.
|
|
*/
|
|
if (tpkt->ackm_pkt.is_ack_eliciting) {
|
|
OSSL_ACKM_PROBE_INFO *probe_info
|
|
= ossl_ackm_get0_probe_request(txp->args.ackm);
|
|
|
|
if (enc_level == QUIC_ENC_LEVEL_INITIAL
|
|
&& probe_info->anti_deadlock_initial > 0)
|
|
--probe_info->anti_deadlock_initial;
|
|
|
|
if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE
|
|
&& probe_info->anti_deadlock_handshake > 0)
|
|
--probe_info->anti_deadlock_handshake;
|
|
|
|
if (a.allow_force_ack_eliciting /* (i.e., not for 0-RTT) */
|
|
&& probe_info->pto[pn_space] > 0)
|
|
--probe_info->pto[pn_space];
|
|
}
|
|
|
|
ossl_quic_fifd_pkt_discard_unreliable(&txp->fifd, tpkt);
|
|
|
|
return rc;
|
|
}
|