diff mbox series

[dunfell] systemd: Backport systemd-resolved: use hostname for certificate validation in DoT

Message ID 20231010224748.267388-1-marex@denx.de
State Accepted, archived
Commit 6b4a583169ae40a8d51e7ffa33785409b5111a81
Headers show
Series [dunfell] systemd: Backport systemd-resolved: use hostname for certificate validation in DoT | expand

Commit Message

Marek Vasut Oct. 10, 2023, 10:47 p.m. UTC
Widely accepted certificates for IP addresses are expensive and only
affordable for larger organizations. Therefore if the user provides
the hostname in the DNS= option, we should use it instead of the IP
address.

This fixes https://nvd.nist.gov/vuln/detail/CVE-2018-21029 per
suggestion https://github.com/systemd/systemd-stable/issues/72 .

CVE: CVE-2018-21029
Signed-off-by: Marek Vasut <marex@denx.de>
---
NOTE: Here it would be good if someone took a close look at this backport.
---
Cc: Alban Bedel <alban.bedel@aerq.com>
Cc: Richard Purdie <richard.purdie@linuxfoundation.org>
Cc: Jermain Horsman <jermain.horsman@nedap.com>
Cc: Steve Sakoman <steve@sakoman.com>
---
 .../systemd/systemd/CVE-2018-21029.patch      | 120 ++++++++++++++++++
 meta/recipes-core/systemd/systemd_244.5.bb    |   1 +
 2 files changed, 121 insertions(+)
 create mode 100644 meta/recipes-core/systemd/systemd/CVE-2018-21029.patch
diff mbox series

Patch

diff --git a/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch b/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch
new file mode 100644
index 0000000000..8d3801a248
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/CVE-2018-21029.patch
@@ -0,0 +1,120 @@ 
+From 3f9d9289ee8730a81a0464539f4e1ba2d23d0ce9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
+Date: Tue, 3 Mar 2020 23:31:25 +0000
+Subject: [PATCH] systemd-resolved: use hostname for certificate validation in
+ DoT
+
+Widely accepted certificates for IP addresses are expensive and only
+affordable for larger organizations. Therefore if the user provides
+the hostname in the DNS= option, we should use it instead of the IP
+address.
+
+(cherry picked from commit eec394f10bbfcc3d2fc8504ad8ff5be44231abd5)
+
+CVE: CVE-2018-21029
+Upstream-Status: Backport [ff26d281aec0877b43269f18c6282cd79a7f5529]
+Signed-off-by: Marek Vasut <marex@denx.de>
+---
+ man/resolved.conf.xml                 | 16 +++++++++++-----
+ src/resolve/resolved-dnstls-gnutls.c  | 20 ++++++++++++--------
+ src/resolve/resolved-dnstls-openssl.c | 15 +++++++++++----
+ 3 files changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
+index 818000145b..37161ebcbc 100644
+--- a/man/resolved.conf.xml
++++ b/man/resolved.conf.xml
+@@ -193,11 +193,17 @@
+       <varlistentry>
+         <term><varname>DNSOverTLS=</varname></term>
+         <listitem>
+-        <para>Takes a boolean argument or <literal>opportunistic</literal>.
+-        If true all connections to the server will be encrypted. Note that
+-        this mode requires a DNS server that supports DNS-over-TLS and has
+-        a valid certificate for it's IP. If the DNS server does not support
+-        DNS-over-TLS all DNS requests will fail. When set to <literal>opportunistic</literal>
++        <para>Takes a boolean argument or <literal>opportunistic</literal>. If
++        true all connections to the server will be encrypted. Note that this
++        mode requires a DNS server that supports DNS-over-TLS and has a valid
++        certificate. If the hostname was specified in <varname>DNS=</varname>
++        by using the format format <literal>address#server_name</literal> it
++        is used to validate its certificate and also to enable Server Name
++        Indication (SNI) when opening a TLS connection. Otherwise
++        the certificate is checked against the server's IP.
++        If the DNS server does not support DNS-over-TLS all DNS requests will fail.</para>
++
++        <para>When set to <literal>opportunistic</literal>
+         DNS request are attempted to send encrypted with DNS-over-TLS.
+         If the DNS server does not support TLS, DNS-over-TLS is disabled.
+         Note that this mode makes DNS-over-TLS vulnerable to "downgrade"
+diff --git a/src/resolve/resolved-dnstls-gnutls.c b/src/resolve/resolved-dnstls-gnutls.c
+index ed0a31e8bf..c7215723a7 100644
+--- a/src/resolve/resolved-dnstls-gnutls.c
++++ b/src/resolve/resolved-dnstls-gnutls.c
+@@ -56,15 +56,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
+         }
+ 
+         if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
+-                stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS;
+-                if (server->family == AF_INET) {
+-                        stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr;
+-                        stream->dnstls_data.validation.size = 4;
+-                } else {
+-                        stream->dnstls_data.validation.data = server->address.in6.s6_addr;
+-                        stream->dnstls_data.validation.size = 16;
++                if (server->server_name)
++                        gnutls_session_set_verify_cert(gs, server->server_name, 0);
++                else {
++                        stream->dnstls_data.validation.type = GNUTLS_DT_IP_ADDRESS;
++                        if (server->family == AF_INET) {
++                                stream->dnstls_data.validation.data = (unsigned char*) &server->address.in.s_addr;
++                                stream->dnstls_data.validation.size = 4;
++                        } else {
++                                stream->dnstls_data.validation.data = server->address.in6.s6_addr;
++                                stream->dnstls_data.validation.size = 16;
++                        }
++                        gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
+                 }
+-                gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
+         }
+ 
+         gnutls_handshake_set_timeout(gs, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
+diff --git a/src/resolve/resolved-dnstls-openssl.c b/src/resolve/resolved-dnstls-openssl.c
+index 85e202ff74..007aedaa5b 100644
+--- a/src/resolve/resolved-dnstls-openssl.c
++++ b/src/resolve/resolved-dnstls-openssl.c
+@@ -6,6 +6,7 @@
+ 
+ #include <openssl/bio.h>
+ #include <openssl/err.h>
++#include <openssl/x509v3.h>
+ 
+ #include "io-util.h"
+ #include "resolved-dns-stream.h"
+@@ -78,13 +79,19 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
+ 
+         if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
+                 X509_VERIFY_PARAM *v;
+-                const unsigned char *ip;
+ 
+                 SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
+                 v = SSL_get0_param(s);
+-                ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
+-                if (!X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)))
+-                        return -ECONNREFUSED;
++                if (server->server_name) {
++                        X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
++                        if (X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
++                                return -ECONNREFUSED;
++                } else {
++                        const unsigned char *ip;
++                        ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
++                        if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
++                                return -ECONNREFUSED;
++                }
+         }
+ 
+         ERR_clear_error();
+-- 
+2.40.1
+
diff --git a/meta/recipes-core/systemd/systemd_244.5.bb b/meta/recipes-core/systemd/systemd_244.5.bb
index bd66d82932..8b2f47b92f 100644
--- a/meta/recipes-core/systemd/systemd_244.5.bb
+++ b/meta/recipes-core/systemd/systemd_244.5.bb
@@ -31,6 +31,7 @@  SRC_URI += "file://touchscreen.rules \
            file://network-fix-Link-reference-counter-issue.patch \
            file://rm-rf-refactor-rm-rf-children-split-out-body-of-directory.patch \
            file://rm-rf-optionally-fsync-after-removing-directory-tree.patch \
+           file://CVE-2018-21029.patch \
            file://CVE-2021-3997-1.patch \
            file://CVE-2021-3997-2.patch \
            file://CVE-2021-3997-3.patch \