The MULTIBLOCK code uses a "jumbo" sized write buffer which it allocates
and then frees later. Pipelining however introduced multiple pipelines. It
keeps track of how many pipelines are initialised using numwpipes.
Unfortunately the MULTIBLOCK code was not updating this when in deallocated
its buffers, leading to a buffer being marked as initialised but set to
NULL.
RT#4618
Reviewed-by: Rich Salz <rsalz@openssl.org>
- wb->buf = OPENSSL_malloc(packlen);
- if (wb->buf == NULL) {
+ if (!ssl3_setup_write_buffer(s, 1, packlen)) {
SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE);
return -1;
}
SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE);
return -1;
}
} else if (tot == len) { /* done? */
} else if (tot == len) { /* done? */
- OPENSSL_free(wb->buf); /* free jumbo buffer */
- wb->buf = NULL;
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
return tot;
}
n = (len - tot);
for (;;) {
if (n < 4 * max_send_fragment) {
return tot;
}
n = (len - tot);
for (;;) {
if (n < 4 * max_send_fragment) {
- OPENSSL_free(wb->buf); /* free jumbo buffer */
- wb->buf = NULL;
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
sizeof(mb_param), &mb_param);
if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */
sizeof(mb_param), &mb_param);
if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */
- OPENSSL_free(wb->buf); /* free jumbo buffer */
- wb->buf = NULL;
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
i = ssl3_write_pending(s, type, &buf[tot], nw);
if (i <= 0) {
if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) {
i = ssl3_write_pending(s, type, &buf[tot], nw);
if (i <= 0) {
if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) {
- OPENSSL_free(wb->buf);
- wb->buf = NULL;
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
}
s->rlayer.wnum = tot;
return i;
}
if (i == (int)n) {
}
s->rlayer.wnum = tot;
return i;
}
if (i == (int)n) {
- OPENSSL_free(wb->buf); /* free jumbo buffer */
- wb->buf = NULL;
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
return tot + i;
}
n -= i;
return tot + i;
}
n -= i;
}
if (s->rlayer.numwpipes < numpipes)
}
if (s->rlayer.numwpipes < numpipes)
- if (!ssl3_setup_write_buffer(s, numpipes))
+ if (!ssl3_setup_write_buffer(s, numpipes, 0))
return -1;
if (totlen == 0 && !create_empty_fragment)
return -1;
if (totlen == 0 && !create_empty_fragment)
void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
void SSL3_BUFFER_release(SSL3_BUFFER *b);
__owur int ssl3_setup_read_buffer(SSL *s);
void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
void SSL3_BUFFER_release(SSL3_BUFFER *b);
__owur int ssl3_setup_read_buffer(SSL *s);
-__owur int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes);
+__owur int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len);
int ssl3_release_read_buffer(SSL *s);
int ssl3_release_write_buffer(SSL *s);
int ssl3_release_read_buffer(SSL *s);
int ssl3_release_write_buffer(SSL *s);
-int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes)
+int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len)
- size_t len, align = 0, headerlen;
+ size_t align = 0, headerlen;
SSL3_BUFFER *wb;
unsigned int currpipe;
s->rlayer.numwpipes = numwpipes;
SSL3_BUFFER *wb;
unsigned int currpipe;
s->rlayer.numwpipes = numwpipes;
-
- if (SSL_IS_DTLS(s))
- headerlen = DTLS1_RT_HEADER_LENGTH + 1;
- else
- headerlen = SSL3_RT_HEADER_LENGTH;
+ if (len == 0) {
+ if (SSL_IS_DTLS(s))
+ headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+ else
+ headerlen = SSL3_RT_HEADER_LENGTH;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
- align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+ align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
- len = s->max_send_fragment
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+ len = s->max_send_fragment
+ + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
- if (ssl_allow_compression(s))
- len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+ if (ssl_allow_compression(s))
+ len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
- len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ }
wb = RECORD_LAYER_get_wbuf(&s->rlayer);
for (currpipe = 0; currpipe < numwpipes; currpipe++) {
wb = RECORD_LAYER_get_wbuf(&s->rlayer);
for (currpipe = 0; currpipe < numwpipes; currpipe++) {
{
if (!ssl3_setup_read_buffer(s))
return 0;
{
if (!ssl3_setup_read_buffer(s))
return 0;
- if (!ssl3_setup_write_buffer(s, 1))
+ if (!ssl3_setup_write_buffer(s, 1, 0))