Commit c58099b
committed
ipc4: helper: reject module creation for non-existent pipeline
comp_new_ipc4() copied the host-supplied ppl_instance_id into
ipc_config.pipeline_id without verifying that the referenced pipeline
exists. The module_adapter creation path then does:
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE,
config->pipeline_id,
IPC_COMP_IGNORE_REMOTE);
if (ipc_pipe)
dev->pipeline = ipc_pipe->pipeline; /* skipped when NULL */
so when the pipeline is missing the lookup returns NULL, the assignment
is skipped, and the component is created with dev->pipeline left unset.
A gateway module such as the copier then dereferences that NULL pointer
while wiring the graph, e.g. copier_dai_init() writing
pipeline->source_comp / pipeline->sink_comp, giving a NULL-pointer SEGV
reachable from a single unprivileged IPC.
The case
--------
The offending IPC stream carries one meaningful command: a
MODULE / INIT_INSTANCE request for a copier-class module
(module_id 26, instance_id 36) whose extension.ppl_instance_id names a
parent pipeline (id 90) for which no GLB / CREATE_PIPELINE command was
ever sent. That pipeline is therefore absent from ipc->comp_list. IPC4
mandates that the host create the pipeline before instantiating any
module inside it; here that ordering is violated, so the invariant
"an INIT_INSTANCE always targets an existing pipeline" does not hold.
The firmware accepted the request anyway, allocated the component, ran
module_init() -> copier_init() -> copier_dai_create(), and
copier_dai_init() performed a WRITE to the source_comp field (offset
0x54) through the NULL dev->pipeline, faulting on the zero page:
ERROR: SEGV on unknown address 0x00000054 (WRITE)
copier_dai_init -> copier_dai_create -> copier_init
-> module_init -> module_adapter_new_ext -> module_adapter_new
-> comp_new_ipc4 -> ipc4_init_module_instance
-> ipc4_process_module_message -> ipc_cmd
All three copier gateway variants are affected (copier_host_create,
copier_dai_create and copier_ipcgtw_create all pass dev->pipeline down),
and any future module reading dev->pipeline during init would hit the
same latent NULL.
Fix
---
Reject the request at the common creation entry point: in
comp_new_ipc4(), before the component is allocated, look up the parent
pipeline and fail with a NULL return (reported to the host as
IPC4_MOD_NOT_INITIALIZED) when it does not exist. This fails fast with
no partially-initialized component to unwind, and the later
module_adapter lookup is then guaranteed to succeed. The lookup uses
IPC_COMP_ALL so it stays core-agnostic: a valid parent pipeline may run
on a different core than the module being instantiated (e.g. a DP module
scheduled on a separate core).
Not every module has a parent pipeline, so the check cannot enforce a
blanket "a live component always belongs to a live pipeline" invariant:
base firmware modules such as the probe are instantiated with the
reserved ppl_instance_id value IPC4_INVALID_PIPELINE_ID (0xFF), which is
not a pipeline id. Exempt that value from the check so those modules are
still accepted; they never dereference dev->pipeline.
That exemption means a gateway copier could still be created with no
pipeline (0xFF). Unlike the probe, a gateway copier must be wired into
the graph and therefore requires a live pipeline, so reject it in
copier_init() before the gateway create path dereferences dev->pipeline.
Together this keeps "no NULL dev->pipeline dereference is reachable from
a single IPC" for every module driver.
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>1 parent 22cae7b commit c58099b
3 files changed
Lines changed: 28 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
179 | 189 | | |
180 | 190 | | |
181 | 191 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
154 | 158 | | |
155 | 159 | | |
156 | 160 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
148 | 162 | | |
149 | 163 | | |
150 | 164 | | |
| |||
0 commit comments