summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIwan Timmer <irtimmer@gmail.com>2019-06-15 22:05:00 +0200
committerIwan Timmer <irtimmer@gmail.com>2019-06-15 22:46:55 +0200
commitab8cd6c9681abadf738dc10d4bcf10aa2ba59bc2 (patch)
tree5291b3a8b62dee5ba99875d821e5923cf8c06502
parent53d64ebb304599995bf7b1fc6b9b54dc3c8421fd (diff)
downloadsystemd-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.c22
-rw-r--r--src/resolve/resolved-dnstls-openssl.h1
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;
};