From: sashiko-bot@kernel.org
To: "Mayuresh Chitale" <mayuresh.chitale@oss.qualcomm.com>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v6 02/14] hwtracing: gtrace: Initial implementation of gtrace framework
Date: Thu, 01 Oct 2026 05:37:59 +0000 [thread overview]
Message-ID: <20261001053800.0D3771F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261001052243.3042627-3-mayuresh.chitale@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] gtrace: Use-After-Free due to missing reference counting in lookup functions
- [High] gtrace: Topological Use-After-Free due to dangling dest_comp pointer
- [Medium] gtrace: Resource leak and UAF in per-CPU bound component handling
- [Medium] gtrace: gtrace_match_id() fails to match hardware components with version 0
- [Medium] gtrace: Null pointer dereference in gtrace_match_device()
- [Low] gtrace: Silent connection drop in gtrace_setup_inconn()
--
commit c892ee2c4bffce2e20b5a0429f11f8530ff96b44
Author: Anup Patel <anup.patel@oss.qualcomm.com>
Subject: hwtracing: gtrace: Initial implementation of gtrace framework
This commit implements a generic, architecture-neutral tracing framework
where trace components form a graph-like topology. It includes the core bus,
registration helpers, and a mechanism for polling component registers.
> diff --git a/drivers/hwtracing/gtrace/gtrace-core.c b/drivers/hwtracing/gtrace/gtrace-core.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/hwtracing/gtrace/gtrace-core.c
[ ... ]
> +const struct gtrace_component_id *gtrace_match_id(struct gtrace_component *comp,
> + const struct gtrace_component_id *ids)
> +{
> + const struct gtrace_component_id *id;
> +
> + for (id = ids; id->version; id++) {
[Severity: Medium]
Is it possible for a valid hardware component to have a version of 0? If an
architecture provides a hardware component with a 0 version identifier,
would this loop terminate prematurely and silently fail to probe the hardware?
Also, could the `ids` pointer be NULL here if a driver registers without
providing an `id_table`? Dereferencing it unconditionally might cause a
kernel panic if the framework does not strictly enforce `id_table` presence
during registration.
> + if (comp->id.type != id->type)
> + continue;
> +
> + return id;
> + }
> +
> + return NULL;
> +}
> +EXPORT_SYMBOL_GPL(gtrace_match_id);
> +
> +static int gtrace_match_device(struct device *dev, const struct device_driver *drv)
> +{
> + const struct gtrace_driver *gtdrv = to_gtrace_driver(drv);
> + struct gtrace_component *comp = to_gtrace_component(dev);
> +
> + return gtrace_match_id(comp, gtdrv->id_table) ? 1 : 0;
[Severity: Medium]
Is it guaranteed that `gtdrv->id_table` is non-NULL before passing it to
gtrace_match_id()? If a driver does not provide an `id_table`, does this
lead to a NULL pointer dereference inside gtrace_match_id()?
> +}
[ ... ]
> +static int gtrace_match_fwnode(struct device *dev, void *data)
> +{
> + struct gtrace_component *comp = to_gtrace_component(dev);
> + struct gtrace_fwnode_match_data *d = data;
> +
> + if (device_match_fwnode(&comp->dev, d->fwnode)) {
> + d->match = comp;
[Severity: High]
Does assigning the matched component here without calling get_device() leave
the object lifecycle unprotected? Could callers of gtrace_find_by_fwnode()
end up dereferencing a freed pointer if the target component is concurrently
unregistered and freed?
> + return 1;
> + }
> +
> + return 0;
> +}
[ ... ]
> +struct gtrace_component *gtrace_cpu_source(unsigned int cpu)
> +{
> + if (!cpu_present(cpu))
> + return NULL;
> +
> + return per_cpu(gtrace_cpu_source_comp, cpu);
[Severity: High]
Like the fwnode lookup above, does returning a raw pointer here without
reference counting or locking create a use-after-free window? If the
component is concurrently unregistered via gtrace_unregister_component()
while the caller is still using the pointer, could this result in memory
corruption?
> +}
> +EXPORT_SYMBOL_GPL(gtrace_cpu_source);
[ ... ]
> +static int gtrace_setup_inconn(struct device *dev, void *data)
> +{
> + struct gtrace_component *comp = to_gtrace_component(dev);
> + struct gtrace_platform_data *pdata = comp->pdata;
> + struct gtrace_connection *conn = data;
> + int i;
> +
> + if (device_match_fwnode(&comp->dev, conn->dest_fwnode)) {
> + for (i = 0; i < pdata->nr_inconns; i++) {
> + if (pdata->inconns[i])
> + continue;
> + pdata->inconns[i] = conn;
> + return 1;
> + }
> + }
> +
> + return 0;
[Severity: Low]
If the destination array is fully populated and we exhaust the loop, should
this return a negative error code instead of 0? Returning 0 appears to hide
the connection failure and silently drops the input connection when a
matching destination is found but saturated.
> +}
[ ... ]
> +struct gtrace_component *gtrace_register_component(struct gtrace_component_id *id,
> + const char *name,
> + struct gtrace_platform_data *pdata)
> +{
[ ... ]
> + if (comp->pdata->bound_cpu >= 0) {
> + gtrace_get_component(comp);
> + per_cpu(gtrace_cpu_source_comp, comp->pdata->bound_cpu) = comp;
[Severity: Medium]
What happens if multiple components are mistakenly mapped to the same CPU?
Does unconditionally overwriting the per-CPU variable here leak the reference
count of the previously stored component?
> + }
> +
> + mutex_unlock(>race_mutex);
> +
> + return comp;
> +
> +err_out_unlock:
> + mutex_unlock(>race_mutex);
> +err_out:
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(gtrace_register_component);
> +
> +void gtrace_unregister_component(struct gtrace_component *comp)
> +{
> + struct gtrace_component *c;
> +
> + mutex_lock(>race_mutex);
> +
> + if (comp->pdata->bound_cpu >= 0) {
> + c = per_cpu(gtrace_cpu_source_comp, comp->pdata->bound_cpu);
> + per_cpu(gtrace_cpu_source_comp, comp->pdata->bound_cpu) = NULL;
> + gtrace_put_component(c);
[Severity: Medium]
Does fetching and putting whatever is currently in the per-CPU variable
without verifying it matches `comp` risk dropping the reference on the wrong
component? If the per-CPU pointer was overwritten by a second component,
does this prematurely free the second one while the first one is being
unregistered?
> + }
> +
> + gtrace_cleanup_inconns_from_outconns(comp);
> + device_unregister(&comp->dev);
[Severity: High]
Does this sequence unregister the component without clearing the pointers
pointing to it from its source components' outconns arrays? When a trace
path is later constructed and walks the source's outconns, would it
dereference the freed dest_comp and cause a topological use-after-free?
> +
> + mutex_unlock(>race_mutex);
> +}
> +EXPORT_SYMBOL_GPL(gtrace_unregister_component);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261001052243.3042627-1-mayuresh.chitale@oss.qualcomm.com?part=2
next prev parent reply other threads:[~2026-10-01 5:38 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 5:22 [PATCH v6 00/14] Linux RISC-V trace framework and drivers Mayuresh Chitale
2026-10-01 5:22 ` [PATCH v6 01/14] dt-bindings: Add RISC-V trace component bindings Mayuresh Chitale
2026-10-01 5:33 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 02/14] hwtracing: gtrace: Initial implementation of gtrace framework Mayuresh Chitale
2026-10-01 5:37 ` sashiko-bot [this message]
2026-10-01 5:22 ` [PATCH v6 03/14] gtrace: Add RISC-V platform driver for the " Mayuresh Chitale
2026-10-01 5:36 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 04/14] gtrace: Add functions to create/destroy a trace component path Mayuresh Chitale
2026-10-01 5:36 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 05/14] gtrace: Add functions to start/stop tracing on a " Mayuresh Chitale
2026-10-01 5:36 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 06/14] gtrace: Add RISC-V Trace encoder driver Mayuresh Chitale
2026-10-01 5:34 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 07/14] gtrace: Add function to copy into perf AUX buffer Mayuresh Chitale
2026-10-01 5:40 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 08/14] perf: Add gtrace AUX buffer trace format type Mayuresh Chitale
2026-10-01 5:22 ` [PATCH v6 09/14] gtrace: Add RISC-V Trace ramsink driver Mayuresh Chitale
2026-10-01 5:42 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 10/14] riscv: Enable DMA_RESTRICTED_POOL in defconfig Mayuresh Chitale
2026-10-01 5:22 ` [PATCH v6 11/14] gtrace: Add perf driver for tracing using perf tool Mayuresh Chitale
2026-10-01 5:44 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 12/14] perf tools: Add RISC-V trace PMU record capabilities Mayuresh Chitale
2026-10-01 5:22 ` [PATCH v6 13/14] perf tools: Initial support for gtrace decoder Mayuresh Chitale
2026-10-01 5:35 ` sashiko-bot
2026-10-01 5:22 ` [PATCH v6 14/14] MAINTAINERS: Add entry for RISC-V trace framework Mayuresh Chitale
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261001053800.0D3771F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=mayuresh.chitale@oss.qualcomm.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox