From 16880f90e2ddfd7ad80b21f435193de9bdcbe5ae Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 29 Aug 2024 10:58:01 +0200 Subject: [PATCH] core: fix deleting internal global DNS configuration The tracking of variable "has_intern" in intern_config_read() is wrong: we set it when adding any entry to the keyfile, but then we remove the global DNS section without updating the variable. The effect is that the function might return an empty keyfile instead of NULL. Fix this by moving the check on global DNS above. Fixes: 55c204b9a357 ('core: add support for reading global DNS configuration from keyfile') (cherry picked from commit 07113dde30df4f52383161a60ba2baf220305758) (cherry picked from commit 0a1b642a2d6ae960d563a96f2088a00dded61445) (cherry picked from commit 23143c5e3e77b0409e539e1203d1f778029e2014) (cherry picked from commit f3006bf8940bd38d43ab4dbe791eb6aa00eab128) --- src/core/nm-config.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/core/nm-config.c b/src/core/nm-config.c index b8df41b723..4b22efea7b 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -1558,6 +1558,7 @@ intern_config_read(const char *filename, gs_strfreev char **groups = NULL; guint g, k; gboolean has_intern = FALSE; + gboolean has_global_dns; g_return_val_if_fail(filename, NULL); @@ -1575,6 +1576,8 @@ intern_config_read(const char *filename, goto out; } + has_global_dns = nm_config_keyfile_has_global_dns_config(keyfile_conf, FALSE); + groups = g_key_file_get_groups(keyfile, NULL); for (g = 0; groups && groups[g]; g++) { gs_strfreev char **keys = NULL; @@ -1591,6 +1594,21 @@ intern_config_read(const char *filename, is_intern = NM_STR_HAS_PREFIX(group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN); is_atomic = !is_intern && _is_atomic_section(atomic_section_prefixes, group); + if (has_global_dns + && (nm_streq0(group, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS) + || NM_STR_HAS_PREFIX_WITH_MORE( + group, + NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN))) { + /* + * If user configuration specifies global DNS options, the DNS + * options in internal configuration must be deleted. Otherwise, a + * deletion of options from user configuration may cause the + * internal options to appear again. + */ + needs_rewrite = TRUE; + continue; + } + if (is_atomic) { gs_free char *conf_section_was = NULL; gs_free char *conf_section_is = NULL; @@ -1684,26 +1702,6 @@ intern_config_read(const char *filename, } out: - /* - * If user configuration specifies global DNS options, the DNS - * options in internal configuration must be deleted. Otherwise, a - * deletion of options from user configuration may cause the - * internal options to appear again. - */ - if (nm_config_keyfile_has_global_dns_config(keyfile_conf, FALSE)) { - if (g_key_file_remove_group(keyfile_intern, - NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, - NULL)) - needs_rewrite = TRUE; - for (g = 0; groups && groups[g]; g++) { - if (NM_STR_HAS_PREFIX(groups[g], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN) - && groups[g][NM_STRLEN(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)]) { - g_key_file_remove_group(keyfile_intern, groups[g], NULL); - needs_rewrite = TRUE; - } - } - } - g_key_file_unref(keyfile); if (out_needs_rewrite)