Files
Open_Ultra_SAST/benchmarks/pairs/vfc/openssl-cve-2024-4741/fixed.c
T
Marius Ciepluch 0116f9bea6 feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
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.
2026-09-04 16:45:38 +02:00

179 lines
5.5 KiB
C

/* Provenance: openssl/openssl ssl3_read_n (fixed).
* repo: openssl/openssl
* commit: 2d05959073c4bf8803401668b9df85931a08e020
* parent: b3f0eb0a295f58f16ba43ba99dad70d4ee5c437d
* commit_url: https://github.com/openssl/openssl/commit/2d05959073c4bf8803401668b9df85931a08e020
* cve: CVE-2024-4741
* license: Apache-2.0
* function: ssl3_read_n
* relpath: ssl/record/rec_layer_s3.c
*/
int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
size_t *readbytes)
{
/*
* If extend == 0, obtain new n-byte packet; if extend == 1, increase
* packet by another n bytes. The packet will be in the sub-array of
* s->rlayer.rbuf.buf specified by s->rlayer.packet and
* s->rlayer.packet_length. (If s->rlayer.read_ahead is set, 'max' bytes may
* be stored in rbuf [plus s->rlayer.packet_length bytes if extend == 1].)
* if clearold == 1, move the packet to the start of the buffer; if
* clearold == 0 then leave any old packets where they were
*/
size_t len, left, align = 0;
unsigned char *pkt;
SSL3_BUFFER *rb;
if (n == 0)
return 0;
rb = &s->rlayer.rbuf;
if (rb->buf == NULL)
if (!ssl3_setup_read_buffer(s)) {
/* SSLfatal() already called */
return -1;
}
left = rb->left;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
#endif
if (!extend) {
/* start with empty packet ... */
if (left == 0)
rb->offset = align;
s->rlayer.packet = rb->buf + rb->offset;
s->rlayer.packet_length = 0;
/* ... now we can act as if 'extend' was set */
}
if (!ossl_assert(s->rlayer.packet != NULL)) {
/* does not happen */
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return -1;
}
len = s->rlayer.packet_length;
pkt = rb->buf + align;
/*
* Move any available bytes to front of buffer: 'len' bytes already
* pointed to by 'packet', 'left' extra ones at the end
*/
if (s->rlayer.packet != pkt && clearold == 1) {
memmove(pkt, s->rlayer.packet, len + left);
s->rlayer.packet = pkt;
rb->offset = len + align;
}
/*
* For DTLS/UDP reads should not span multiple packets because the read
* operation returns the whole packet at once (as long as it fits into
* the buffer).
*/
if (SSL_IS_DTLS(s)) {
if (left == 0 && extend)
return 0;
if (left > 0 && n > left)
n = left;
}
/* if there is enough in the buffer from a previous read, take some */
if (left >= n) {
s->rlayer.packet_length += n;
rb->left = left - n;
rb->offset += n;
*readbytes = n;
return 1;
}
/* else we need to read more data */
if (n > rb->len - rb->offset) {
/* does not happen */
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return -1;
}
/*
* Ktls always reads full records.
* Also, we always act like read_ahead is set for DTLS.
*/
if (!BIO_get_ktls_recv(s->rbio) && !s->rlayer.read_ahead
&& !SSL_IS_DTLS(s)) {
/* ignore max parameter */
max = n;
} else {
if (max < n)
max = n;
if (max > rb->len - rb->offset)
max = rb->len - rb->offset;
}
while (left < n) {
size_t bioread = 0;
int ret;
/*
* Now we have len+left bytes at the front of s->s3.rbuf.buf and
* need to read in more until we have len+n (up to len+max if
* possible)
*/
clear_sys_error();
if (s->rbio != NULL) {
s->rwstate = SSL_READING;
ret = BIO_read(s->rbio, pkt + len + left, max - left);
if (ret >= 0)
bioread = ret;
if (ret <= 0
&& !BIO_should_retry(s->rbio)
&& BIO_eof(s->rbio)) {
if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN);
s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
} else {
/*
* This reason code is part of the API and may be used by
* applications for control flow decisions.
*/
SSLfatal(s, SSL_AD_DECODE_ERROR,
SSL_R_UNEXPECTED_EOF_WHILE_READING);
}
}
} else {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET);
ret = -1;
}
if (ret <= 0) {
rb->left = left;
if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
if (len + left == 0)
ssl3_release_read_buffer(s);
return ret;
}
left += bioread;
/*
* reads should *never* span multiple packets for DTLS because the
* underlying transport protocol is message oriented as opposed to
* byte oriented as in the TLS case.
*/
if (SSL_IS_DTLS(s)) {
if (n > left)
n = left; /* makes the while condition false */
}
}
/* done reading, now the book-keeping */
rb->offset += n;
rb->left = left - n;
s->rlayer.packet_length += n;
s->rwstate = SSL_NOTHING;
*readbytes = n;
return 1;
}