[PATCH] dns: clean up error paths in dns-manager

2016-01-20 Thread Dan Williams
Specifically for resolvconf, if the write succeeded, but the pclose()
failed error would be left NULL and SR_ERROR would be returned, which
caused a crash in nm_dns_manager_end_updates().
---
 src/dns-manager/nm-dns-manager.c | 126 ++-
 1 file changed, 58 insertions(+), 68 deletions(-)

diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 01e8bf1..48f44ea 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -357,7 +357,6 @@ dispatch_netconfig (NMDnsManager *self,
 
if (searches) {
str = g_strjoinv (" ", searches);
-
write_to_netconfig (self, fd, "DNSSEARCH", str);
g_free (str);
}
@@ -405,10 +404,9 @@ write_resolv_conf (FILE *f,
char **options,
GError **error)
 {
-   char *searches_str = NULL;
-   char *nameservers_str = NULL;
-   char *options_str = NULL;
-   gboolean retval = FALSE;
+   gs_free char *searches_str = NULL;
+   gs_free char *nameservers_str = NULL;
+   gs_free char *options_str = NULL;
char *tmp_str;
GString *str;
int i;
@@ -425,12 +423,9 @@ write_resolv_conf (FILE *f,
g_free (tmp_str);
}
 
-   str = g_string_new ("");
-
if (nameservers) {
-   int num = g_strv_length (nameservers);
-
-   for (i = 0; i < num; i++) {
+   str = g_string_new ("");
+   for (i = 0; i < g_strv_length (nameservers); i++) {
if (i == 3) {
g_string_append (str, "# ");
g_string_append (str, _("NOTE: the libc 
resolver may not support more than 3 nameservers."));
@@ -443,28 +438,22 @@ write_resolv_conf (FILE *f,
g_string_append (str, nameservers[i]);
g_string_append_c (str, '\n');
}
+   nameservers_str = g_string_free (str, FALSE);
}
 
-   nameservers_str = g_string_free (str, FALSE);
-
if (fprintf (f, "# Generated by NetworkManager\n%s%s%s",
 searches_str ? searches_str : "",
-nameservers_str,
-options_str ? options_str : "") > 0)
-   retval = TRUE;
-   else {
+nameservers_str ? nameservers_str : "",
+options_str ? options_str : "") < 0) {
g_set_error (error,
 NM_MANAGER_ERROR,
 NM_MANAGER_ERROR_FAILED,
 "Could not write " _PATH_RESCONF ": %s\n",
 g_strerror (errno));
+   return FALSE;
}
 
-   g_free (searches_str);
-   g_free (nameservers_str);
-   g_free (options_str);
-
-   return retval;
+   return TRUE;
 }
 
 static SpawnResult
@@ -474,10 +463,11 @@ dispatch_resolvconf (NMDnsManager *self,
  char **options,
  GError **error)
 {
-   char *cmd;
+   gs_free char *cmd = NULL;
FILE *f;
-   gboolean retval = FALSE;
+   gboolean success = FALSE;
int errnosv, err;
+   GError *local = NULL;
 
if (!g_file_test (RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) {
g_set_error_literal (error,
@@ -487,39 +477,45 @@ dispatch_resolvconf (NMDnsManager *self,
return SR_NOTFOUND;
}
 
-   if (searches || nameservers) {
-   cmd = g_strconcat (RESOLVCONF_PATH, " -a ", "NetworkManager", 
NULL);
-   _LOGI ("Writing DNS information to %s", RESOLVCONF_PATH);
-   if ((f = popen (cmd, "w")) == NULL)
-   g_set_error (error,
-NM_MANAGER_ERROR,
-NM_MANAGER_ERROR_FAILED,
-"Could not write to %s: %s\n",
-RESOLVCONF_PATH,
-g_strerror (errno));
-   else {
-   retval = write_resolv_conf (f, searches, nameservers, 
options, error);
-   err = pclose (f);
-   if (err < 0) {
-   errnosv = errno;
-   g_set_error (error, G_IO_ERROR, 
g_io_error_from_errno (errnosv),
-"Failed to close pipe to 
resolvconf: %d", errnosv);
-   retval = FALSE;
-   } else if (err > 0) {
-   _LOGW ("resolvconf failed with status %d", err);
-   retval = FALSE;
-   }
-   }
-   } else {
-   cmd = g_strconcat (RESOLVCONF_PATH, " -d ", "NetworkManager", 
NULL);
+   if (!searches && !nameservers) {

Re: [PATCH] dns: clean up error paths in dns-manager

2016-01-20 Thread Thomas Haller
On Wed, 2016-01-20 at 13:52 -0600, Dan Williams wrote:
> Specifically for resolvconf, if the write succeeded, but the pclose()
> failed error would be left NULL and SR_ERROR would be returned, which
> caused a crash in nm_dns_manager_end_updates().
> ---
>  src/dns-manager/nm-dns-manager.c | 126 ++---
> --
>  1 file changed, 58 insertions(+), 68 deletions(-)
> 
> diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-
> dns-manager.c
> index 01e8bf1..48f44ea 100644
> --- a/src/dns-manager/nm-dns-manager.c
> +++ b/src/dns-manager/nm-dns-manager.c
> @@ -357,7 +357,6 @@ dispatch_netconfig (NMDnsManager *self,
>  
>   if (searches) {
>   str = g_strjoinv (" ", searches);
> -
>   write_to_netconfig (self, fd, "DNSSEARCH", str);
>   g_free (str);
>   }
> @@ -405,10 +404,9 @@ write_resolv_conf (FILE *f,
> char **options,
> GError **error)
>  {
> - char *searches_str = NULL;
> - char *nameservers_str = NULL;
> - char *options_str = NULL;
> - gboolean retval = FALSE;
> + gs_free char *searches_str = NULL;
> + gs_free char *nameservers_str = NULL;
> + gs_free char *options_str = NULL;
>   char *tmp_str;
>   GString *str;
>   int i;
> @@ -425,12 +423,9 @@ write_resolv_conf (FILE *f,
>   g_free (tmp_str);
>   }
>  
> - str = g_string_new ("");
> -
>   if (nameservers) {
> - int num = g_strv_length (nameservers);
> -
> - for (i = 0; i < num; i++) {
> + str = g_string_new ("");
> + for (i = 0; i < g_strv_length (nameservers); i++) {

for (i = 0; nameservers[i]; i++)

otherwise, the length has to be calculated needlessly and for each
iteration.


>   if (i == 3) {
>   g_string_append (str, "# ");
>   g_string_append (str, _("NOTE: the
> libc resolver may not support more than 3 nameservers."));
> @@ -443,28 +438,22 @@ write_resolv_conf (FILE *f,
>   g_string_append (str, nameservers[i]);
>   g_string_append_c (str, '\n');
>   }
> + nameservers_str = g_string_free (str, FALSE);
>   }
>  
> - nameservers_str = g_string_free (str, FALSE);
> -
>   if (fprintf (f, "# Generated by NetworkManager\n%s%s%s",
>    searches_str ? searches_str : "",
> -  nameservers_str,
> -  options_str ? options_str : "") > 0)
> - retval = TRUE;
> - else {
> +  nameservers_str ? nameservers_str : "",
> +  options_str ? options_str : "") < 0) {
>   g_set_error (error,
>    NM_MANAGER_ERROR,
>    NM_MANAGER_ERROR_FAILED,
>    "Could not write " _PATH_RESCONF ":
> %s\n",
>    g_strerror (errno));
> + return FALSE;
>   }
>  
> - g_free (searches_str);
> - g_free (nameservers_str);
> - g_free (options_str);
> -
> - return retval;
> + return TRUE;
>  }
>  
>  static SpawnResult
> @@ -474,10 +463,11 @@ dispatch_resolvconf (NMDnsManager *self,
>   char **options,
>   GError **error)
>  {
> - char *cmd;
> + gs_free char *cmd = NULL;
>   FILE *f;
> - gboolean retval = FALSE;
> + gboolean success = FALSE;
>   int errnosv, err;
> + GError *local = NULL;
>  
>   if (!g_file_test (RESOLVCONF_PATH,
> G_FILE_TEST_IS_EXECUTABLE)) {
>   g_set_error_literal (error,
> @@ -487,39 +477,45 @@ dispatch_resolvconf (NMDnsManager *self,
>   return SR_NOTFOUND;
>   }
>  
> - if (searches || nameservers) {
> - cmd = g_strconcat (RESOLVCONF_PATH, " -a ",
> "NetworkManager", NULL);
> - _LOGI ("Writing DNS information to %s",
> RESOLVCONF_PATH);
> - if ((f = popen (cmd, "w")) == NULL)
> - g_set_error (error,
> -  NM_MANAGER_ERROR,
> -  NM_MANAGER_ERROR_FAILED,
> -  "Could not write to %s: %s\n",
> -  RESOLVCONF_PATH,
> -  g_strerror (errno));
> - else {
> - retval = write_resolv_conf (f, searches,
> nameservers, options, error);
> - err = pclose (f);
> - if (err < 0) {
> - errnosv = errno;
> - g_set_error (error, G_IO_ERROR,
> g_io_error_from_errno (errnosv),
> -  "Failed to close pipe
> to resolvconf: %d", errnosv);
> - retval = FALSE;
> - } else if (err > 0) {
> - _LOGW ("resolvconf failed with
> status