From c4b39914c4ea7b17e1cbdfd7efd487b4d35abbb1 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 19 Dec 2025 17:24:20 +0100 Subject: [PATCH 1/2] core: limit the result from the helper to 32MiB --- src/core/nm-core-utils.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 2c2e282ff7..219964f0f6 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -5459,6 +5459,14 @@ helper_have_data(int fd, GIOCondition condition, gpointer user_data) n_read = nm_utils_fd_read(fd, &info->in_buffer); _LOG2T(info, "read returns %ld", (long) n_read); + if (info->in_buffer.len > 32 * 1024 * 1024) { + helper_complete(info, + g_error_new_literal(NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "the output is larger than 32MiB")); + return G_SOURCE_CONTINUE; + } + if (n_read > 0) return G_SOURCE_CONTINUE; From eb784c3f2768b726e9ef191e9bd73253ebb921ab Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 19 Dec 2025 17:50:15 +0100 Subject: [PATCH 2/2] supplicant: properly validate blobs The purpose of the validation is to check that we pass to the supplicant a configuration that it can understand. For certificates and keys we enforce a maximum length of 64KiB; that means that the value of the property we send (i.e. the file path or the blob id) can be at most 64KiB. Instead we wrongly checked the size of the blob data. Fix the validation. Also, enforce a maximum blob size of 32MiB. Fixes: e85cc46d0b36 ('core: pass certificates as blobs to supplicant for private connections') --- src/core/supplicant/nm-supplicant-config.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index fd360e7238..d026d9ccad 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -206,20 +206,30 @@ nm_supplicant_config_add_blob(NMSupplicantConfig *self, ConfigOption *old_opt; ConfigOption *opt; NMSupplOptType type; - const guint8 *data; gsize data_len; + gs_free char *full_value = NULL; g_return_val_if_fail(NM_IS_SUPPLICANT_CONFIG(self), FALSE); g_return_val_if_fail(key != NULL, FALSE); g_return_val_if_fail(value != NULL, FALSE); g_return_val_if_fail(blobid != NULL, FALSE); - data = g_bytes_get_data(value, &data_len); + g_bytes_get_data(value, &data_len); g_return_val_if_fail(data_len > 0, FALSE); - priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE(self); + if (data_len > 32 * 1024 * 1024) { + g_set_error(error, + NM_SUPPLICANT_ERROR, + NM_SUPPLICANT_ERROR_CONFIG, + "blob '%s' is larger than 32MiB", + key); + return FALSE; + } - type = nm_supplicant_settings_verify_setting(key, (const char *) data, data_len); + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE(self); + full_value = g_strdup_printf("blob://%s", blobid); + + type = nm_supplicant_settings_verify_setting(key, full_value, strlen(full_value)); if (type == NM_SUPPL_OPT_TYPE_INVALID) { g_set_error(error, NM_SUPPLICANT_ERROR, @@ -240,7 +250,7 @@ nm_supplicant_config_add_blob(NMSupplicantConfig *self, } opt = g_slice_new0(ConfigOption); - opt->value = g_strdup_printf("blob://%s", blobid); + opt->value = g_steal_pointer(&full_value); opt->len = strlen(opt->value); opt->type = type;