diff options
author | Ondrej Holy <oholy@redhat.com> | 2016-07-29 12:48:19 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2016-07-29 12:53:58 +0200 |
commit | 8398c16b048ad39bd35ecadfed5c2e8f38770125 (patch) | |
tree | b936c3770b86adb9b99fcf5171431459eb289f3e /daemon | |
parent | ed27604c55a144bebc88c85bab5032b5f584d5cd (diff) | |
download | gvfs-8398c16b048ad39bd35ecadfed5c2e8f38770125.tar.gz |
dnssd: Fix crashes when mount failed
Mount operation might fail if you run multiple mount operations
concurrently. Backend memory is released consequently. Unfortunatelly
AvahiServiceResolvers are not freed and thus resolve_callback might
be called after backend finalize, which causes segmentation faults.
This patch fixes this and also some other memory leaks.
https://bugzilla.gnome.org/show_bug.cgi?id=631023
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/gvfsbackenddnssd.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/daemon/gvfsbackenddnssd.c b/daemon/gvfsbackenddnssd.c index 51eac9b4..31bf54c9 100644 --- a/daemon/gvfsbackenddnssd.c +++ b/daemon/gvfsbackenddnssd.c @@ -131,6 +131,7 @@ struct _GVfsBackendDnsSd GList *files; /* list of LinkFiles */ GList *browsers; + GList *resolvers; }; typedef struct _GVfsBackendDnsSd GVfsBackendDnsSd; @@ -566,19 +567,19 @@ resolve_callback (AvahiServiceResolver *r, char *path; if (event == AVAHI_RESOLVER_FAILURE) - return; - + goto out; + /* Link-local ipv6 address, can't make a uri from this, ignore */ if (address->proto == AVAHI_PROTO_INET6 && address->data.ipv6.address[0] == 0xfe && address->data.ipv6.address[1] == 0x80) - return; - + goto out; + file = lookup_link_file_by_name_and_type (backend, name, type); if (file != NULL) - return; + goto out; file = link_file_new (name, type, domain, host_name, protocol, address, port, txt); @@ -591,6 +592,10 @@ resolve_callback (AvahiServiceResolver *r, path, NULL); g_free (path); + + out: + backend->resolvers = g_list_remove (backend->resolvers, r); + avahi_service_resolver_free (r); } static void @@ -617,18 +622,15 @@ browse_callback (AvahiServiceBrowser *b, case AVAHI_BROWSER_NEW: client = get_global_avahi_client (); - - /* We ignore the returned resolver object. In the callback - function we free it. If the server is terminated before - the callback function is called the server will free - the resolver for us. */ - + sr = avahi_service_resolver_new (client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, backend); if (sr == NULL) g_warning ("Failed to resolve service name '%s': %s\n", name, avahi_strerror (avahi_client_errno (client))); - + else + backend->resolvers = g_list_prepend (backend->resolvers, sr); + break; case AVAHI_BROWSER_REMOVE: @@ -799,6 +801,9 @@ g_vfs_backend_dns_sd_finalize (GObject *object) dnssd_backends = g_list_remove (dnssd_backends, backend); + remove_browsers (backend); + g_list_free_full (backend->resolvers, (GDestroyNotify)avahi_service_resolver_free); + if (backend->mount_spec) g_mount_spec_unref (backend->mount_spec); |