diff --git a/ChangeLog b/ChangeLog index 6f429d3f58..69830143a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-10-26 Dan Williams + + * src/named-manager/nm-named-manager.c + - (rewrite_resolv_conf): clean up error handling to avoid double-free by + not calling fclose() twice on some error conditions + 2007-10-26 Dan Williams * src/nm-activation-request.c diff --git a/src/named-manager/nm-named-manager.c b/src/named-manager/nm-named-manager.c index cab7331c22..6073fb92fd 100644 --- a/src/named-manager/nm-named-manager.c +++ b/src/named-manager/nm-named-manager.c @@ -270,48 +270,85 @@ rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error) return TRUE; } - if ((f = fopen (tmp_resolv_conf, "w")) == NULL) - goto lose; + if ((f = fopen (tmp_resolv_conf, "w")) == NULL) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not open " RESOLV_CONF ": %s\n", + g_strerror (errno)); + return FALSE; + } - if (fprintf (f, "%s","# generated by NetworkManager, do not edit!\n\n") < 0) - goto lose; + if (fprintf (f, "%s","# generated by NetworkManager, do not edit!\n\n") < 0) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not write " RESOLV_CONF ": %s\n", + g_strerror (errno)); + fclose (f); + return FALSE; + } searches = compute_searches (mgr, config); if (mgr->priv->use_named == TRUE) { /* Using caching-nameserver & local DNS */ - if (fprintf (f, "%s%s%s", "; Use a local caching nameserver controlled by NetworkManager\n\n", searches, "\nnameserver 127.0.0.1\n") < 0) - goto lose; + if (fprintf (f, + "%s%s%s", + "; Use a local caching nameserver controlled by NetworkManager\n\n", + searches, + "\nnameserver 127.0.0.1\n") < 0) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not write " RESOLV_CONF ": %s\n", + g_strerror (errno)); + fclose (f); + g_free (searches); + return FALSE; + } } else { /* Using glibc resolver */ char *nameservers = compute_nameservers (mgr, config); - fprintf (f, "%s\n\n", searches); - g_free (searches); - - fprintf (f, "%s\n\n", nameservers); + if ((fprintf (f, "%s\n\n", searches) < 0) || + (fprintf (f, "%s\n\n", nameservers) < 0)) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not write to " RESOLV_CONF ": %s\n", + g_strerror (errno)); + g_free (nameservers); + g_free (searches); + fclose (f); + return FALSE; + } g_free (nameservers); } + g_free (searches); - if (fclose (f) < 0) - goto lose; + if (fclose (f) < 0) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not close " RESOLV_CONF ": %s\n", + g_strerror (errno)); + return FALSE; + } - if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) - goto lose; + if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) { + g_set_error (error, + NM_NAMED_MANAGER_ERROR, + NM_NAMED_MANAGER_ERROR_SYSTEM, + "Could not replace " RESOLV_CONF ": %s\n", + g_strerror (errno)); + return FALSE; + } nm_system_update_dns (); return TRUE; - -lose: - g_free (searches); - fclose (f); - g_set_error (error, - NM_NAMED_MANAGER_ERROR, - NM_NAMED_MANAGER_ERROR_SYSTEM, - "Could not update " RESOLV_CONF ": %s\n", g_strerror (errno)); - return FALSE; } static const char *