mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-03 06:47:04 -04:00
security: fix multiple issues in pulse module implementations
- module-zeroconf-publish: guard spa_hook_remove of impl_listener with a flag to prevent operating on uninitialized hook when unload is called after a partial load failure; bail out of create_service when pw_properties_new fails to prevent NULL dereference in publish_service - module-device-restore: add missing NULL check after message_alloc in emit_event; make manager_events static const - module-jackdbus-detect: fix memory leak on error paths in prepare by using goto out instead of early return; free props/sink_props/source_props in unload - module-roc-sink-input: add missing valid_args whitelist - module-rtp-recv: add missing valid_args whitelist - module-rtp-send: add missing valid_args whitelist - module-gsettings: add missing NULL check after strdup in load_group Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8e596bd85f
commit
ef2541a1ef
7 changed files with 72 additions and 9 deletions
|
|
@ -118,6 +118,8 @@ static void emit_event(struct subscribe *s, uint32_t type, uint32_t idx)
|
|||
{
|
||||
struct client *client = s->client;
|
||||
struct message *msg = message_alloc(client->impl, -1, 0);
|
||||
if (msg == NULL)
|
||||
return;
|
||||
|
||||
pw_log_info("[%s] EVENT index:%u name:%s %d/%d", client->name,
|
||||
s->data->module->index, s->data->module->info->name, type, idx);
|
||||
|
|
@ -161,7 +163,7 @@ static void manager_updated(void *data, struct pw_manager_object *object)
|
|||
}
|
||||
}
|
||||
|
||||
struct pw_manager_events manager_events = {
|
||||
static const struct pw_manager_events manager_events = {
|
||||
PW_VERSION_MANAGER_EVENTS,
|
||||
.added = manager_updated,
|
||||
.updated = manager_updated,
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ static int load_group(struct module_gsettings_data *d, const struct info *info)
|
|||
return -errno;
|
||||
|
||||
g->name = strdup(info->name);
|
||||
if (g->name == NULL) {
|
||||
free(g);
|
||||
return -errno;
|
||||
}
|
||||
g->module = module_create(d->module->impl, info->module[i], info->args[i]);
|
||||
if (g->module == NULL) {
|
||||
pw_log_info("can't create module:%s args:%s: %m",
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ static int module_jackdbus_detect_unload(struct module *module)
|
|||
d->mod = NULL;
|
||||
}
|
||||
|
||||
pw_properties_free(d->props);
|
||||
pw_properties_free(d->sink_props);
|
||||
pw_properties_free(d->source_props);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +176,7 @@ static int module_jackdbus_detect_prepare(struct module * const module)
|
|||
spa_zero(info);
|
||||
if ((res = module_args_to_audioinfo_keys(module->impl, props, NULL, NULL,
|
||||
"sink_channels", "sink_channel_map", &info)) < 0) {
|
||||
return res;
|
||||
goto out;
|
||||
} else {
|
||||
audioinfo_to_properties(&info, sink_props);
|
||||
}
|
||||
|
|
@ -194,7 +198,7 @@ static int module_jackdbus_detect_prepare(struct module * const module)
|
|||
spa_zero(info);
|
||||
if ((res = module_args_to_audioinfo_keys(module->impl, props, NULL, NULL,
|
||||
"source_channels", "source_channel_map", &info)) < 0) {
|
||||
return res;
|
||||
goto out;
|
||||
} else {
|
||||
audioinfo_to_properties(&info, source_props);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,8 +199,22 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
static const char* const valid_args[] = {
|
||||
"sink",
|
||||
"sink_input_properties",
|
||||
"resampler_profile",
|
||||
"fec_code",
|
||||
"sess_latency_msec",
|
||||
"local_ip",
|
||||
"local_source_port",
|
||||
"local_repair_port",
|
||||
"local_control_port",
|
||||
NULL
|
||||
};
|
||||
|
||||
DEFINE_MODULE_INFO(module_roc_sink_input) = {
|
||||
.name = "module-roc-sink-input",
|
||||
.valid_args = valid_args,
|
||||
.prepare = module_roc_sink_input_prepare,
|
||||
.load = module_roc_sink_input_load,
|
||||
.unload = module_roc_sink_input_unload,
|
||||
|
|
|
|||
|
|
@ -168,8 +168,17 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
static const char* const valid_args[] = {
|
||||
"sink",
|
||||
"sap_address",
|
||||
"latency_msec",
|
||||
"stream_properties",
|
||||
NULL
|
||||
};
|
||||
|
||||
DEFINE_MODULE_INFO(module_rtp_recv) = {
|
||||
.name = "module-rtp-recv",
|
||||
.valid_args = valid_args,
|
||||
.prepare = module_rtp_recv_prepare,
|
||||
.load = module_rtp_recv_load,
|
||||
.unload = module_rtp_recv_unload,
|
||||
|
|
|
|||
|
|
@ -266,8 +266,27 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
static const char* const valid_args[] = {
|
||||
"source",
|
||||
"format",
|
||||
"channels",
|
||||
"rate",
|
||||
"destination_ip",
|
||||
"source_ip",
|
||||
"port",
|
||||
"mtu",
|
||||
"loop",
|
||||
"ttl",
|
||||
"inhibit_auto_suspend",
|
||||
"stream_name",
|
||||
"stream_properties",
|
||||
"enable_opus",
|
||||
NULL
|
||||
};
|
||||
|
||||
DEFINE_MODULE_INFO(module_rtp_send) = {
|
||||
.name = "module-rtp-send",
|
||||
.valid_args = valid_args,
|
||||
.prepare = module_rtp_send_prepare,
|
||||
.load = module_rtp_send_load,
|
||||
.unload = module_rtp_send_unload,
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ struct module_zeroconf_publish_data {
|
|||
struct pw_zeroconf *zeroconf;
|
||||
struct spa_hook zeroconf_listener;
|
||||
|
||||
unsigned int impl_listening:1;
|
||||
|
||||
/* lists of services */
|
||||
struct spa_list pending;
|
||||
struct spa_list published;
|
||||
|
|
@ -299,6 +301,11 @@ static struct service *create_service(struct module_zeroconf_publish_data *d, st
|
|||
|
||||
fill_service_data(d, s, o);
|
||||
|
||||
if (s->props == NULL) {
|
||||
spa_list_remove(&s->link);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pw_log_debug("service %p: created for object %p", s, o);
|
||||
|
||||
return s;
|
||||
|
|
@ -475,6 +482,7 @@ static int module_zeroconf_publish_load(struct module *module)
|
|||
&zeroconf_events, data);
|
||||
|
||||
impl_add_listener(module->impl, &data->impl_listener, &impl_events, data);
|
||||
data->impl_listening = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -484,7 +492,10 @@ static int module_zeroconf_publish_unload(struct module *module)
|
|||
struct module_zeroconf_publish_data *d = module->user_data;
|
||||
struct service *s;
|
||||
|
||||
if (d->impl_listening) {
|
||||
spa_hook_remove(&d->impl_listener);
|
||||
d->impl_listening = false;
|
||||
}
|
||||
|
||||
unpublish_all_services(d);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue