systemd: fix CVE-2020-13529

Backport patches to fix CVE-2020-13529.

(From OE-Core rev: 5dcd5071d61fac240ff95672778ba1eed1312a03)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Chen Qi
2021-07-28 23:27:52 -07:00
committed by Richard Purdie
parent a21c4c48b8
commit f8c1193fb5
5 changed files with 353 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
From ac6c7f2d2389c5c0ae90554a58f1c75f60cc8e5a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 24 Jun 2021 00:48:23 +0900
Subject: [PATCH] sd-dhcp-client: check error earlier and reduce indentation
Upstream-Status: Backport
CVE: CVE-2020-13529
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
src/libsystemd-network/sd-dhcp-client.c | 128 ++++++++++++------------
1 file changed, 64 insertions(+), 64 deletions(-)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index d472fcd941..86bc3c6181 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1770,21 +1770,21 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
case DHCP_STATE_SELECTING:
r = client_handle_offer(client, message, len);
- if (r >= 0) {
+ if (r == -ENOMSG)
+ return 0; /* invalid message, let's ignore it */
+ if (r < 0)
+ goto error;
- client->state = DHCP_STATE_REQUESTING;
- client->attempt = 0;
+ client->state = DHCP_STATE_REQUESTING;
+ client->attempt = 0;
- r = event_reset_time(client->event, &client->timeout_resend,
- clock_boottime_or_monotonic(),
- 0, 0,
- client_timeout_resend, client,
- client->event_priority, "dhcp4-resend-timer", true);
- if (r < 0)
- goto error;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ 0, 0,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp4-resend-timer", true);
+ if (r < 0)
+ goto error;
break;
@@ -1794,47 +1794,9 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
case DHCP_STATE_REBINDING:
r = client_handle_ack(client, message, len);
- if (r >= 0) {
- client->start_delay = 0;
- (void) event_source_disable(client->timeout_resend);
- client->receive_message =
- sd_event_source_unref(client->receive_message);
- client->fd = safe_close(client->fd);
-
- if (IN_SET(client->state, DHCP_STATE_REQUESTING,
- DHCP_STATE_REBOOTING))
- notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
- else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
- notify_event = r;
-
- client->state = DHCP_STATE_BOUND;
- client->attempt = 0;
-
- client->last_addr = client->lease->address;
-
- r = client_set_lease_timeouts(client);
- if (r < 0) {
- log_dhcp_client(client, "could not set lease timeouts");
- goto error;
- }
-
- r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
- if (r < 0) {
- log_dhcp_client(client, "could not bind UDP socket");
- goto error;
- }
-
- client->fd = r;
-
- client_initialize_io_events(client, client_receive_message_udp);
-
- if (notify_event) {
- client_notify(client, notify_event);
- if (client->state == DHCP_STATE_STOPPED)
- return 0;
- }
-
- } else if (r == -EADDRNOTAVAIL) {
+ if (r == -ENOMSG)
+ return 0; /* invalid message, let's ignore it */
+ if (r == -EADDRNOTAVAIL) {
/* got a NAK, let's restart the client */
client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
@@ -1853,21 +1815,59 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
return 0;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
+ }
+ if (r < 0)
+ goto error;
+
+ client->start_delay = 0;
+ (void) event_source_disable(client->timeout_resend);
+ client->receive_message = sd_event_source_unref(client->receive_message);
+ client->fd = safe_close(client->fd);
+
+ if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING))
+ notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
+ else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
+ notify_event = r;
+
+ client->state = DHCP_STATE_BOUND;
+ client->attempt = 0;
+
+ client->last_addr = client->lease->address;
+
+ r = client_set_lease_timeouts(client);
+ if (r < 0) {
+ log_dhcp_client(client, "could not set lease timeouts");
+ goto error;
+ }
+
+ r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
+ if (r < 0) {
+ log_dhcp_client(client, "could not bind UDP socket");
+ goto error;
+ }
+
+ client->fd = r;
+
+ client_initialize_io_events(client, client_receive_message_udp);
+
+ if (notify_event) {
+ client_notify(client, notify_event);
+ if (client->state == DHCP_STATE_STOPPED)
+ return 0;
+ }
break;
case DHCP_STATE_BOUND:
r = client_handle_forcerenew(client, message, len);
- if (r >= 0) {
- r = client_timeout_t1(NULL, 0, client);
- if (r < 0)
- goto error;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
+ if (r == -ENOMSG)
+ return 0; /* invalid message, let's ignore it */
+ if (r < 0)
+ goto error;
+
+ r = client_timeout_t1(NULL, 0, client);
+ if (r < 0)
+ goto error;
break;

View File

@@ -0,0 +1,66 @@
From 875f3773e383d99e7d43020f02acad7681a05914 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 24 Jun 2021 00:51:52 +0900
Subject: [PATCH] sd-dhcp-client: shorten code a bit
Upstream-Status: Backport
CVE: CVE-2020-13529
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
src/libsystemd-network/sd-dhcp-client.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 86bc3c6181..ef3a7d2c6b 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1760,7 +1760,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX];
- int r = 0, notify_event = 0;
+ int r, notify_event = 0;
assert(client);
assert(client->event);
@@ -1783,9 +1783,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
0, 0,
client_timeout_resend, client,
client->event_priority, "dhcp4-resend-timer", true);
- if (r < 0)
- goto error;
-
break;
case DHCP_STATE_REBOOTING:
@@ -1813,7 +1810,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client->start_delay = CLAMP(client->start_delay * 2,
RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
-
return 0;
}
if (r < 0)
@@ -1866,19 +1862,18 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
goto error;
r = client_timeout_t1(NULL, 0, client);
- if (r < 0)
- goto error;
-
break;
case DHCP_STATE_INIT:
case DHCP_STATE_INIT_REBOOT:
-
+ r = 0;
break;
case DHCP_STATE_STOPPED:
r = -EINVAL;
goto error;
+ default:
+ assert_not_reached("invalid state");
}
error:

View File

@@ -0,0 +1,69 @@
From 0ad3b0fffe622bffbe9f380c3e4cb99b0961bef5 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 24 Jun 2021 01:14:12 +0900
Subject: [PATCH] sd-dhcp-client: logs when dhcp client unexpectedly gains a
new lease
Previously, such situation is handled silently.
Upstream-Status: Backport
CVE: CVE-2020-13529
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
src/libsystemd-network/sd-dhcp-client.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index ef3a7d2c6b..04a75c6966 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1760,7 +1760,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX];
- int r, notify_event = 0;
+ int r, notify_event;
assert(client);
assert(client->event);
@@ -1815,16 +1815,16 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
if (r < 0)
goto error;
+ if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING))
+ notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
+ else
+ notify_event = r;
+
client->start_delay = 0;
(void) event_source_disable(client->timeout_resend);
client->receive_message = sd_event_source_unref(client->receive_message);
client->fd = safe_close(client->fd);
- if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING))
- notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
- else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
- notify_event = r;
-
client->state = DHCP_STATE_BOUND;
client->attempt = 0;
@@ -1846,12 +1846,13 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client_initialize_io_events(client, client_receive_message_udp);
- if (notify_event) {
+ if (IN_SET(client->state, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING) &&
+ notify_event == SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
+ /* FIXME: hmm, maybe this is a bug... */
+ log_dhcp_client(client, "client_handle_ack() returned SD_DHCP_CLIENT_EVENT_IP_ACQUIRE while DHCP client is %s the address, skipping callback.",
+ client->state == DHCP_STATE_RENEWING ? "renewing" : "rebinding");
+ else
client_notify(client, notify_event);
- if (client->state == DHCP_STATE_STOPPED)
- return 0;
- }
-
break;
case DHCP_STATE_BOUND:

View File

@@ -0,0 +1,42 @@
From ae18277a6cfd04af8a914780f04a867254ab2341 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Thu, 24 Jun 2021 01:22:07 +0900
Subject: [PATCH] sd-dhcp-client: tentatively ignore FORCERENEW command
This makes DHCP client ignore FORCERENEW requests, as unauthenticated
FORCERENEW requests causes a security issue (TALOS-2020-1142, CVE-2020-13529).
Let's re-enable this after RFC3118 (Authentication for DHCP Messages)
and/or RFC6704 (Forcerenew Nonce Authentication) are implemented.
Fixes #16774.
Upstream-Status: Backport
CVE: CVE-2020-13529
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
src/libsystemd-network/sd-dhcp-client.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 04a75c6966..54eb3a2ab0 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1536,9 +1536,17 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
if (r != DHCP_FORCERENEW)
return -ENOMSG;
+#if 0
log_dhcp_client(client, "FORCERENEW");
return 0;
+#else
+ /* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP
+ * Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW
+ * requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */
+ log_dhcp_client(client, "Received FORCERENEW, ignoring.");
+ return -ENOMSG;
+#endif
}
static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {

View File

@@ -27,6 +27,10 @@ SRC_URI += "file://touchscreen.rules \
file://0001-logind-Restore-chvt-as-non-root-user-without-polkit.patch \
file://0027-proc-dont-trigger-mount-error-with-invalid-options-o.patch \
file://0001-analyze-resolve-executable-path-if-it-is-relative.patch \
file://0001-sd-dhcp-client-check-error-earlier-and-reduce-indent.patch \
file://0002-sd-dhcp-client-shorten-code-a-bit.patch \
file://0003-sd-dhcp-client-logs-when-dhcp-client-unexpectedly-ga.patch \
file://0004-sd-dhcp-client-tentatively-ignore-FORCERENEW-command.patch \
"
# patches needed by musl