From 7d781e696f63c14758fbea8d3639869e7878cf05 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 6 Oct 2025 14:34:15 +0200 Subject: [PATCH] profiler: avoid null dereference Avoid shadowing some variables from the parent block. The node of a target can be NULL when the target is running in another instance. We already do some checks for this but make sure we never deref the NULL pointer. Fixes #4922 --- src/modules/module-profiler.c | 66 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/modules/module-profiler.c b/src/modules/module-profiler.c index d6ed9914c..be1da5724 100644 --- a/src/modules/module-profiler.c +++ b/src/modules/module-profiler.c @@ -266,54 +266,58 @@ static void context_do_profile(void *data) SPA_POD_Int(a->xrun_count)); spa_list_for_each(t, &node->rt.target_list, link) { - struct pw_impl_node *n = t->node; - struct pw_node_activation *na; + struct pw_impl_node *tn = t->node; + struct pw_node_activation *ta = t->activation; struct spa_fraction latency; - struct pw_node_activation *a = n->rt.target.activation; - struct spa_io_position *pos = &a->position; + bool async; + int64_t prev_signal_time; if (t->id == id) continue; - if (n != NULL) { - latency = n->latency; - if (n->force_quantum != 0) - latency.num = n->force_quantum; - if (n->force_rate != 0) - update_denom(&latency, n->force_rate); - else if (n->rate.denom != 0) - update_denom(&latency, n->rate.denom); + if (tn != NULL) { + latency = tn->latency; + if (tn->force_quantum != 0) + latency.num = tn->force_quantum; + if (tn->force_rate != 0) + update_denom(&latency, tn->force_rate); + else if (tn->rate.denom != 0) + update_denom(&latency, tn->rate.denom); + async = tn->async; + prev_signal_time = tn->rt.target.activation->prev_signal_time; } else { spa_zero(latency); + async = false; + prev_signal_time = ta->prev_signal_time; } - na = t->activation; spa_pod_builder_prop(&b, SPA_PROFILER_followerBlock, 0); spa_pod_builder_add_struct(&b, SPA_POD_Int(t->id), SPA_POD_String(t->name), - SPA_POD_Long(a->prev_signal_time), - SPA_POD_Long(n->async ? na->prev_signal_time : na->signal_time), - SPA_POD_Long(n->async ? na->prev_awake_time : na->awake_time), - SPA_POD_Long(n->async ? na->prev_finish_time : na->finish_time), - SPA_POD_Int(na->status), + SPA_POD_Long(prev_signal_time), + SPA_POD_Long(async ? ta->prev_signal_time : ta->signal_time), + SPA_POD_Long(async ? ta->prev_awake_time : ta->awake_time), + SPA_POD_Long(async ? ta->prev_finish_time : ta->finish_time), + SPA_POD_Int(ta->status), SPA_POD_Fraction(&latency), - SPA_POD_Int(na->xrun_count), - SPA_POD_Bool(n->async)); + SPA_POD_Int(ta->xrun_count), + SPA_POD_Bool(async)); - if (n->driver) { + if (tn && tn->driver) { + struct spa_io_position *tpos = &tn->rt.target.activation->position; spa_pod_builder_prop(&b, SPA_PROFILER_followerClock, 0); spa_pod_builder_add_struct(&b, - SPA_POD_Int(pos->clock.id), - SPA_POD_String(pos->clock.name), - SPA_POD_Long(pos->clock.nsec), - SPA_POD_Fraction(&pos->clock.rate), - SPA_POD_Long(pos->clock.position), - SPA_POD_Long(pos->clock.duration), - SPA_POD_Long(pos->clock.delay), - SPA_POD_Double(pos->clock.rate_diff), - SPA_POD_Long(pos->clock.next_nsec), - SPA_POD_Long(pos->clock.xrun)); + SPA_POD_Int(tpos->clock.id), + SPA_POD_String(tpos->clock.name), + SPA_POD_Long(tpos->clock.nsec), + SPA_POD_Fraction(&tpos->clock.rate), + SPA_POD_Long(tpos->clock.position), + SPA_POD_Long(tpos->clock.duration), + SPA_POD_Long(tpos->clock.delay), + SPA_POD_Double(tpos->clock.rate_diff), + SPA_POD_Long(tpos->clock.next_nsec), + SPA_POD_Long(tpos->clock.xrun)); } } spa_pod_builder_pop(&b, &f[0]);