Fix crash as a result of MULTIBLOCK
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>
This commit is contained in:
parent
0fae81501a
commit
58c27c207d
3 changed files with 29 additions and 30 deletions
|
@ -423,23 +423,21 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
|
|||
else
|
||||
packlen *= 4;
|
||||
|
||||
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;
|
||||
}
|
||||
wb->len = packlen;
|
||||
} 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) {
|
||||
OPENSSL_free(wb->buf); /* free jumbo buffer */
|
||||
wb->buf = NULL;
|
||||
/* free jumbo buffer */
|
||||
ssl3_release_write_buffer(s);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -471,8 +469,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
|
|||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -502,15 +500,15 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
|
|||
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) {
|
||||
OPENSSL_free(wb->buf); /* free jumbo buffer */
|
||||
wb->buf = NULL;
|
||||
/* free jumbo buffer */
|
||||
ssl3_release_write_buffer(s);
|
||||
return tot + i;
|
||||
}
|
||||
n -= i;
|
||||
|
@ -650,7 +648,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -69,7 +69,7 @@ void SSL3_BUFFER_clear(SSL3_BUFFER *b);
|
|||
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);
|
||||
|
||||
|
|
|
@ -74,33 +74,34 @@ int ssl3_setup_read_buffer(SSL *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes)
|
||||
int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t len, align = 0, headerlen;
|
||||
size_t align = 0, headerlen;
|
||||
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
|
||||
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
|
||||
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
|
||||
#endif
|
||||
|
||||
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;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
if (ssl_allow_compression(s))
|
||||
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
if (ssl_allow_compression(s))
|
||||
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
#endif
|
||||
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++) {
|
||||
|
@ -125,7 +126,7 @@ int ssl3_setup_buffers(SSL *s)
|
|||
{
|
||||
if (!ssl3_setup_read_buffer(s))
|
||||
return 0;
|
||||
if (!ssl3_setup_write_buffer(s, 1))
|
||||
if (!ssl3_setup_write_buffer(s, 1, 0))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue