Repository navigation
ipc: improve isolation between user and kernel IPC code - #11378
Conversation
With CONFIG_SOF_USERSPACE_LL, struct ipc is placed in a memory partition that the LL and IPC user threads can write. It embedded the IPC send work queue, including the k_thread object of its supervisor thread, and the delayable work item holding the handler the queue calls. A user thread could redirect supervisor execution with a plain store. Move both to kernel-only static storage and add ipc_send_wq_get() for the IPC4 logging code that queues work on it. Signed-off-by: Kai Vehmanen <[email protected]>
There was a problem hiding this comment.
🟡 Changes recommended
A critical startup race allows an active core to overwrite shared pointers before they enter the trusted cache, causing subsequent kernel calls to use attacker-selected pointers.
1 open issue
What changed in this PR
This PR strengthens SOF’s user/kernel IPC isolation by moving privileged work-queue resources out of user-writable state and introducing kernel-side IPC object references.
Changes:
- Move the IPC send queue and delayed work into kernel-only storage.
- Add kernel-side references for IPC synchronization objects and user threads.
- Route logging and secondary-core initialization through dedicated helpers.
| File | Description |
|---|---|
src/ipc/ipc4/logging.c |
Uses the IPC send-queue accessor. |
src/ipc/ipc4/handler-kernel.c |
Delegates secondary-core initialization waiting to a helper. |
src/ipc/ipc-common.c |
Adds kernel-only IPC resources, object references and helper implementations. |
src/include/sof/ipc/common.h |
Removes embedded work-queue objects and declares kernel-context helpers. |
Review effort: Balanced
| return -ENOMEM; | ||
| } | ||
| k_event_init(ipc_user->event[core]); | ||
| ipc_user_kevent[core] = ipc_user->event[core]; |
PR 11378: test resultsRun date: 2026-10-31 04:37 UTC Tested commit: 7bc89bd5a2cfc260571ddb17fd51e8b38558703c |
aaee753 to
9a3f02a
Compare
|
V2 pushed:
|
The kernel side of the user-space IPC handoff took the semaphore, event and thread pointers, and the ipc_user pointer itself, from struct ipc_user and ipc->ipc_user_pdata. Both are writable by user threads, so the kernel could be made to operate on forged kernel objects or write to an address chosen by a user thread. Record these pointers in kernel-only variables at init and use them in ipc_user_forward_cmd(), secondary core setup and ipc_thread_user() when called from kernel context. Move the secondary core boot wait into ipc_user_wait_core_init() so handler-kernel.c no longer reads them, and keep the per-core init_needed flags in kernel-only storage as well. Build new objects in locals and publish them to struct ipc_user only after the kernel-only copies are set. On secondary core bring-up the IPC user thread of the primary core is already running and could otherwise overwrite the fields before they are read back. Add ipc_user_get() for kernel code that needs the ipc_user context and use it in ipc4_user_process_module_message() instead of ipc->ipc_user_pdata. Signed-off-by: Kai Vehmanen <[email protected]>
9a3f02a to
7bc89bd
Compare
|
V3 pushed:
|
|
@kv2019i would you feel up to it and have the time to rework the tests in |

Two patches to lock down kernel IPC resources.