diff options
author | Iwan Timmer <irtimmer@gmail.com> | 2019-06-15 22:05:00 +0200 |
---|---|---|
committer | Iwan Timmer <irtimmer@gmail.com> | 2019-06-15 22:46:55 +0200 |
commit | ab8cd6c9681abadf738dc10d4bcf10aa2ba59bc2 (patch) | |
tree | 5291b3a8b62dee5ba99875d821e5923cf8c06502 | |
parent | 53d64ebb304599995bf7b1fc6b9b54dc3c8421fd (diff) | |
download | systemd-ab8cd6c9681abadf738dc10d4bcf10aa2ba59bc2.tar.gz |
resolved: make no changes to OpenSSL BUF_MEM struct
Fix crash when using OpenSSL 1.1.1c
Fixes: #12763
-rw-r--r-- | src/resolve/resolved-dnstls-openssl.c | 22 | ||||
-rw-r--r-- | 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 f269e4d648..1a21b9224b 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 f0dccf32e6..0fe72afd0a 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; }; |