pipewire: module-zeroconf-discover: handle module destroy events

module-zeroconf-discover loads module-pulse-tunnel for each entity
exposed on the network. Previously, however, the destroy event
of the loaded pulse-tunnel modules were not handled.

This resulted in a use-after-free because both `pw_context_destroy()`
and `module-zeroconf-discover.c:impl_free()` tried to destroy
the pulse-tunnel modules. The reason for that is that since
1de16afc40 the modules
are prepended to the module list of the context, not appended,
therefore modules are destroyed in LIFO order, thus the pulse-tunnel
modules were destroyed before the zeroconf-discover module that
loaded them.

Fix that by handling the destroy event of the loaded pulse-tunnel
modules.

Fixes #1653
This commit is contained in:
Barnabás Pőcze 2021-09-29 10:35:16 +02:00
parent 88d7ea3d88
commit d2f0573369

View file

@ -153,13 +153,7 @@ static struct tunnel *find_tunnel(struct impl *impl, const struct tunnel_info *i
static void free_tunnel(struct tunnel *t)
{
spa_list_remove(&t->link);
if (t->module)
pw_impl_module_destroy(t->module);
free((char*)t->info.name);
free((char*)t->info.type);
free((char*)t->info.domain);
free(t);
pw_impl_module_destroy(t->module);
}
static void impl_free(struct impl *impl)
@ -225,6 +219,25 @@ static void pw_properties_from_avahi_string(const char *key, const char *value,
}
}
static void submodule_destroy(void *data)
{
struct tunnel *t = data;
spa_list_remove(&t->link);
spa_hook_remove(&t->module_listener);
free((char *) t->info.name);
free((char *) t->info.type);
free((char *) t->info.domain);
free(t);
}
static const struct pw_impl_module_events submodule_events = {
PW_VERSION_IMPL_MODULE_EVENTS,
.destroy = submodule_destroy,
};
static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol,
AvahiResolverEvent event, const char *name, const char *type, const char *domain,
const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt,
@ -342,6 +355,9 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr
pw_impl_module_destroy(mod);
goto done;
}
pw_impl_module_add_listener(mod, &t->module_listener, &submodule_events, t);
t->module = mod;
done: