From ab8cd6c9681abadf738dc10d4bcf10aa2ba59bc2 Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Sat, 15 Jun 2019 22:05:00 +0200 Subject: [PATCH] resolved: make no changes to OpenSSL BUF_MEM struct Fix crash when using OpenSSL 1.1.1c Fixes: #12763 --- src/resolve/resolved-dnstls-openssl.c | 22 +++++++++++++--------- src/resolve/resolved-dnstls-openssl.h | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/resolve/resolved-dnstls-openssl.c b/src/resolve/resolved-dnstls-openssl.c index f269e4d6487..1a21b9224b4 100644 --- a/src/resolve/resolved-dnstls-openssl.c +++ b/src/resolve/resolved-dnstls-openssl.c @@ -20,12 +20,12 @@ static int dnstls_flush_write_buffer(DnsStream *stream) { assert(stream); assert(stream->encrypted); - if (stream->dnstls_data.write_buffer->length > 0) { + if (stream->dnstls_data.buffer_offset < stream->dnstls_data.write_buffer->length) { assert(stream->dnstls_data.write_buffer->data); struct iovec iov[1]; - iov[0] = IOVEC_MAKE(stream->dnstls_data.write_buffer->data, - stream->dnstls_data.write_buffer->length); + iov[0] = IOVEC_MAKE(stream->dnstls_data.write_buffer->data + stream->dnstls_data.buffer_offset, + stream->dnstls_data.write_buffer->length - stream->dnstls_data.buffer_offset); ss = dns_stream_writev(stream, iov, 1, DNS_STREAM_WRITE_TLS_DATA); if (ss < 0) { if (ss == -EAGAIN) @@ -33,12 +33,14 @@ static int dnstls_flush_write_buffer(DnsStream *stream) { return ss; } else { - stream->dnstls_data.write_buffer->length -= ss; - stream->dnstls_data.write_buffer->data += ss; + stream->dnstls_data.buffer_offset += ss; - if (stream->dnstls_data.write_buffer->length > 0) { + if (stream->dnstls_data.buffer_offset < stream->dnstls_data.write_buffer->length) { stream->dnstls_events |= EPOLLOUT; return -EAGAIN; + } else { + BIO_reset(SSL_get_wbio(stream->dnstls_data.ssl)); + stream->dnstls_data.buffer_offset = 0; } } } @@ -63,6 +65,7 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { return -ENOMEM; BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer); + stream->dnstls_data.buffer_offset = 0; s = SSL_new(server->dnstls_data.ctx); if (!s) @@ -86,12 +89,13 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { } stream->encrypted = true; + stream->dnstls_data.ssl = TAKE_PTR(s); r = dnstls_flush_write_buffer(stream); - if (r < 0 && r != -EAGAIN) + if (r < 0 && r != -EAGAIN) { + SSL_free(TAKE_PTR(stream->dnstls_data.ssl)); return r; - - stream->dnstls_data.ssl = TAKE_PTR(s); + } return 0; } diff --git a/src/resolve/resolved-dnstls-openssl.h b/src/resolve/resolved-dnstls-openssl.h index f0dccf32e65..0fe72afd0ae 100644 --- a/src/resolve/resolved-dnstls-openssl.h +++ b/src/resolve/resolved-dnstls-openssl.h @@ -18,4 +18,5 @@ struct DnsTlsStreamData { bool shutdown; SSL *ssl; BUF_MEM *write_buffer; + size_t buffer_offset; }; -- 2.39.2