You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
12 KiB
324 lines
12 KiB
From ce8c21737b1b952044219111b2358b1602983138 Mon Sep 17 00:00:00 2001 |
|
From: Thomas Haller <thaller@redhat.com> |
|
Date: Thu, 4 Jan 2018 16:12:40 +0100 |
|
Subject: [PATCH 1/2] dhcp: cleanup handling of ipv4.dhcp-client-id and avoid |
|
assertion failure |
|
|
|
The internal client asserts that the length of the client ID is not more |
|
than MAX_CLIENT_ID_LEN. Avoid that assert by truncating the string. |
|
|
|
Also add new nm_dhcp_client_set_client_id_*() setters, that either |
|
set the ID based on a string (in our common dhclient specific |
|
format), or based on the binary data (as obtained from systemd client). |
|
|
|
Also, add checks and assertions that the client ID which is |
|
set via nm_dhcp_client_set_client_id() is always of length |
|
of at least 2 (as required by rfc2132, section-9.14). |
|
|
|
(cherry picked from commit 686afe531ab3774cd818feda8361de74101971f5) |
|
(cherry picked from commit 41a89aeebac146000de97b778800e755db29568f) |
|
--- |
|
libnm-core/nm-setting-ip4-config.c | 2 +- |
|
src/dhcp/nm-dhcp-client.c | 67 ++++++++++++++++++---- |
|
src/dhcp/nm-dhcp-client.h | 9 ++- |
|
src/dhcp/nm-dhcp-dhclient-utils.c | 8 ++- |
|
src/dhcp/nm-dhcp-systemd.c | 18 ++---- |
|
src/dhcp/nm-dhcp-utils.c | 9 ++- |
|
src/nm-types.h | 2 + |
|
.../src/libsystemd-network/sd-dhcp-client.c | 1 + |
|
8 files changed, 88 insertions(+), 28 deletions(-) |
|
|
|
diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c |
|
index 26e7f5056..d9c0cbb14 100644 |
|
--- a/libnm-core/nm-setting-ip4-config.c |
|
+++ b/libnm-core/nm-setting-ip4-config.c |
|
@@ -191,7 +191,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) |
|
return FALSE; |
|
} |
|
|
|
- if (priv->dhcp_client_id && !strlen (priv->dhcp_client_id)) { |
|
+ if (priv->dhcp_client_id && !priv->dhcp_client_id[0]) { |
|
g_set_error_literal (error, |
|
NM_CONNECTION_ERROR, |
|
NM_CONNECTION_ERROR_INVALID_PROPERTY, |
|
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c |
|
index 20ea092f0..1f19db148 100644 |
|
--- a/src/dhcp/nm-dhcp-client.c |
|
+++ b/src/dhcp/nm-dhcp-client.c |
|
@@ -186,19 +186,69 @@ nm_dhcp_client_get_client_id (NMDhcpClient *self) |
|
return NM_DHCP_CLIENT_GET_PRIVATE (self)->client_id; |
|
} |
|
|
|
+static void |
|
+_set_client_id (NMDhcpClient *self, GBytes *client_id, gboolean take) |
|
+{ |
|
+ NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); |
|
+ |
|
+ nm_assert (!client_id || g_bytes_get_size (client_id) >= 2); |
|
+ |
|
+ if ( priv->client_id == client_id |
|
+ || ( priv->client_id |
|
+ && g_bytes_equal (priv->client_id, client_id))) { |
|
+ if (take && client_id) |
|
+ g_bytes_unref (client_id); |
|
+ return; |
|
+ } |
|
+ |
|
+ if (priv->client_id) |
|
+ g_bytes_unref (priv->client_id); |
|
+ priv->client_id = client_id; |
|
+ if (!take && client_id) |
|
+ g_bytes_ref (client_id); |
|
+} |
|
+ |
|
void |
|
nm_dhcp_client_set_client_id (NMDhcpClient *self, GBytes *client_id) |
|
{ |
|
- NMDhcpClientPrivate *priv; |
|
+ g_return_if_fail (NM_IS_DHCP_CLIENT (self)); |
|
+ g_return_if_fail (!client_id || g_bytes_get_size (client_id) >= 2); |
|
+ |
|
+ _set_client_id (self, client_id, FALSE); |
|
+} |
|
+ |
|
+void |
|
+nm_dhcp_client_set_client_id_bin (NMDhcpClient *self, |
|
+ guint8 type, |
|
+ const guint8 *client_id, |
|
+ gsize len) |
|
+{ |
|
+ guint8 *buf; |
|
+ GBytes *b; |
|
|
|
g_return_if_fail (NM_IS_DHCP_CLIENT (self)); |
|
+ g_return_if_fail (client_id); |
|
+ g_return_if_fail (len > 0); |
|
+ |
|
+ buf = g_malloc (len + 1); |
|
+ buf[0] = type; |
|
+ memcpy (buf + 1, client_id, len); |
|
+ b = g_bytes_new_take (buf, len + 1); |
|
+ _set_client_id (self, b, TRUE); |
|
+} |
|
|
|
- priv = NM_DHCP_CLIENT_GET_PRIVATE (self); |
|
+void |
|
+nm_dhcp_client_set_client_id_str (NMDhcpClient *self, |
|
+ const char *dhcp_client_id) |
|
+{ |
|
+ g_return_if_fail (NM_IS_DHCP_CLIENT (self)); |
|
+ g_return_if_fail (!dhcp_client_id || dhcp_client_id[0]); |
|
|
|
- if (priv->client_id && client_id && g_bytes_equal (priv->client_id, client_id)) |
|
- return; |
|
- g_clear_pointer (&priv->client_id, g_bytes_unref); |
|
- priv->client_id = client_id ? g_bytes_ref (client_id) : NULL; |
|
+ _set_client_id (self, |
|
+ dhcp_client_id |
|
+ ? nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id) |
|
+ : NULL, |
|
+ TRUE); |
|
} |
|
|
|
const char * |
|
@@ -448,7 +498,6 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, |
|
const char *last_ip4_address) |
|
{ |
|
NMDhcpClientPrivate *priv; |
|
- gs_unref_bytes GBytes *tmp = NULL; |
|
|
|
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); |
|
|
|
@@ -462,9 +511,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, |
|
else |
|
_LOGI ("activation: beginning transaction (timeout in %u seconds)", (guint) priv->timeout); |
|
|
|
- if (dhcp_client_id) |
|
- tmp = nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id); |
|
- nm_dhcp_client_set_client_id (self, tmp); |
|
+ nm_dhcp_client_set_client_id_str (self, dhcp_client_id); |
|
|
|
g_clear_pointer (&priv->hostname, g_free); |
|
priv->hostname = g_strdup (hostname); |
|
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h |
|
index 02804002f..2c6341682 100644 |
|
--- a/src/dhcp/nm-dhcp-client.h |
|
+++ b/src/dhcp/nm-dhcp-client.h |
|
@@ -173,7 +173,14 @@ gboolean nm_dhcp_client_handle_event (gpointer unused, |
|
const char *reason, |
|
NMDhcpClient *self); |
|
|
|
-void nm_dhcp_client_set_client_id (NMDhcpClient *self, GBytes *client_id); |
|
+void nm_dhcp_client_set_client_id (NMDhcpClient *self, |
|
+ GBytes *client_id); |
|
+void nm_dhcp_client_set_client_id_bin (NMDhcpClient *self, |
|
+ guint8 type, |
|
+ const guint8 *client_id, |
|
+ gsize len); |
|
+void nm_dhcp_client_set_client_id_str (NMDhcpClient *self, |
|
+ const char *dhcp_client_id); |
|
|
|
/***************************************************************************** |
|
* Client data |
|
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c |
|
index e63e6a869..4df90d76a 100644 |
|
--- a/src/dhcp/nm-dhcp-dhclient-utils.c |
|
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c |
|
@@ -178,7 +178,7 @@ read_client_id (const char *str) |
|
gs_free char *s = NULL; |
|
char *p; |
|
|
|
- g_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG))); |
|
+ nm_assert (!strncmp (str, CLIENTID_TAG, NM_STRLEN (CLIENTID_TAG))); |
|
|
|
str += NM_STRLEN (CLIENTID_TAG); |
|
while (g_ascii_isspace (*str)) |
|
@@ -198,6 +198,9 @@ read_client_id (const char *str) |
|
if (s[strlen (s) - 1] == ';') |
|
s[strlen (s) - 1] = '\0'; |
|
|
|
+ if (!s[0]) |
|
+ return NULL; |
|
+ |
|
return nm_dhcp_utils_client_id_string_to_bytes (s); |
|
} |
|
|
|
@@ -329,8 +332,7 @@ nm_dhcp_dhclient_create_config (const char *interface, |
|
continue; |
|
|
|
/* Otherwise capture and return the existing client id */ |
|
- if (out_new_client_id) |
|
- *out_new_client_id = read_client_id (p); |
|
+ NM_SET_OUT (out_new_client_id, read_client_id (p)); |
|
} |
|
|
|
/* Override config file hostname and use one from the connection */ |
|
diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c |
|
index 9b1a44332..f79b7cb1e 100644 |
|
--- a/src/dhcp/nm-dhcp-systemd.c |
|
+++ b/src/dhcp/nm-dhcp-systemd.c |
|
@@ -489,19 +489,13 @@ _save_client_id (NMDhcpSystemd *self, |
|
const uint8_t *client_id, |
|
size_t len) |
|
{ |
|
- gs_unref_bytes GBytes *b = NULL; |
|
- gs_free char *buf = NULL; |
|
- |
|
g_return_if_fail (self != NULL); |
|
g_return_if_fail (client_id != NULL); |
|
g_return_if_fail (len > 0); |
|
|
|
if (!nm_dhcp_client_get_client_id (NM_DHCP_CLIENT (self))) { |
|
- buf = g_malloc (len + 1); |
|
- buf[0] = type; |
|
- memcpy (buf + 1, client_id, len); |
|
- b = g_bytes_new (buf, len + 1); |
|
- nm_dhcp_client_set_client_id (NM_DHCP_CLIENT (self), b); |
|
+ nm_dhcp_client_set_client_id_bin (NM_DHCP_CLIENT (self), |
|
+ type, client_id, len); |
|
} |
|
} |
|
|
|
@@ -543,7 +537,7 @@ bound4_handle (NMDhcpSystemd *self) |
|
add_requests_to_options (options, dhcp4_requests); |
|
dhcp_lease_save (lease, priv->lease_file); |
|
|
|
- sd_dhcp_client_get_client_id(priv->client4, &type, &client_id, &client_id_len); |
|
+ sd_dhcp_client_get_client_id (priv->client4, &type, &client_id, &client_id_len); |
|
if (client_id) |
|
_save_client_id (self, type, client_id, client_id_len); |
|
|
|
@@ -691,14 +685,14 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last |
|
override_client_id = nm_dhcp_client_get_client_id (client); |
|
if (override_client_id) { |
|
client_id = g_bytes_get_data (override_client_id, &client_id_len); |
|
- g_assert (client_id && client_id_len); |
|
+ nm_assert (client_id && client_id_len >= 2); |
|
sd_dhcp_client_set_client_id (priv->client4, |
|
client_id[0], |
|
client_id + 1, |
|
- client_id_len - 1); |
|
+ NM_MIN (client_id_len - 1, _NM_SD_MAX_CLIENT_ID_LEN)); |
|
} else if (lease) { |
|
r = sd_dhcp_lease_get_client_id (lease, (const void **) &client_id, &client_id_len); |
|
- if (r == 0 && client_id_len) { |
|
+ if (r == 0 && client_id_len >= 2) { |
|
sd_dhcp_client_set_client_id (priv->client4, |
|
client_id[0], |
|
client_id + 1, |
|
diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c |
|
index 4b2d57b90..50ca2abe2 100644 |
|
--- a/src/dhcp/nm-dhcp-utils.c |
|
+++ b/src/dhcp/nm-dhcp-utils.c |
|
@@ -750,8 +750,15 @@ nm_dhcp_utils_client_id_string_to_bytes (const char *client_id) |
|
g_return_val_if_fail (client_id && client_id[0], NULL); |
|
|
|
/* Try as hex encoded */ |
|
- if (strchr (client_id, ':')) |
|
+ if (strchr (client_id, ':')) { |
|
bytes = nm_utils_hexstr2bin (client_id); |
|
+ |
|
+ /* the result must be at least two bytes long, |
|
+ * because @client_id contains a delimiter |
|
+ * but nm_utils_hexstr2bin() does not allow |
|
+ * leading nor trailing delimiters. */ |
|
+ nm_assert (!bytes || g_bytes_get_size (bytes) >= 2); |
|
+ } |
|
if (!bytes) { |
|
/* Fall back to string */ |
|
len = strlen (client_id); |
|
diff --git a/src/nm-types.h b/src/nm-types.h |
|
index cc657397e..02163f87e 100644 |
|
--- a/src/nm-types.h |
|
+++ b/src/nm-types.h |
|
@@ -25,6 +25,8 @@ |
|
#error "nm-utils-private.h" must not be used outside of libnm-core/. Do you want "nm-core-internal.h"? |
|
#endif |
|
|
|
+#define _NM_SD_MAX_CLIENT_ID_LEN (sizeof (guint32) + 128) |
|
+ |
|
/* core */ |
|
typedef struct _NMExportedObject NMExportedObject; |
|
typedef struct _NMActiveConnection NMActiveConnection; |
|
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c |
|
index fc6ad422d..5eab00502 100644 |
|
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c |
|
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c |
|
@@ -311,6 +311,7 @@ int sd_dhcp_client_set_client_id( |
|
assert_return(client, -EINVAL); |
|
assert_return(data, -EINVAL); |
|
assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL); |
|
+ G_STATIC_ASSERT_EXPR (_NM_SD_MAX_CLIENT_ID_LEN == MAX_CLIENT_ID_LEN); |
|
|
|
switch (type) { |
|
|
|
-- |
|
2.14.3 |
|
|
|
|
|
From 161a554575f0e043ecf2d50b6108fa102fa9a982 Mon Sep 17 00:00:00 2001 |
|
From: Thomas Haller <thaller@redhat.com> |
|
Date: Tue, 9 Jan 2018 15:55:23 +0100 |
|
Subject: [PATCH 2/2] dhcp: fix check for client-id in _set_client_id() |
|
|
|
Fixes: 686afe531ab3774cd818feda8361de74101971f5 |
|
(cherry picked from commit 0e1fb1dbd282f546820c1ab8326cf4cf550ae2ae) |
|
(cherry picked from commit 8998ce629da8954a15c3cfc9aadb0d74bbcc116b) |
|
--- |
|
src/dhcp/nm-dhcp-client.c | 1 + |
|
1 file changed, 1 insertion(+) |
|
|
|
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c |
|
index 1f19db148..ea3938d63 100644 |
|
--- a/src/dhcp/nm-dhcp-client.c |
|
+++ b/src/dhcp/nm-dhcp-client.c |
|
@@ -195,6 +195,7 @@ _set_client_id (NMDhcpClient *self, GBytes *client_id, gboolean take) |
|
|
|
if ( priv->client_id == client_id |
|
|| ( priv->client_id |
|
+ && client_id |
|
&& g_bytes_equal (priv->client_id, client_id))) { |
|
if (take && client_id) |
|
g_bytes_unref (client_id); |
|
-- |
|
2.14.3
|
|
|