From 86bd9113201649ac3eb459254ed7994d0e5945df Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 2 Sep 2026 14:11:41 +0300 Subject: [PATCH] ipc: userspace: don't fault when removing an already-sent IPC message z_vrfy_ipc_msg_list_remove() rejected any message that was not currently on ipc->msg_list by failing K_SYSCALL_VERIFY(found), which turns into a kernel oops. But ipc_msg_list_remove() is called from ipc_msg_free() / mod_ipc_msg_free() to drop a message that may or may not still be queued. The common case at stream stop / pipeline delete is freeing a message that has already been sent and dequeued: its list node is self-linked (empty), so it is not "found" and the verifier oopses the LL user thread with: os.z_vrfy_ipc_msg_list_remove: syscall z_vrfy_ipc_msg_list_remove ... failed check: found os.z_fatal_error: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0 Relax the checks to avoid this scenario. If the msg->list is empty, it is safe to call z_impl_ipc_msg_list_remove(). The msg->list pointer itself is already verified with K_SYSCALL_MEMORY_WRITE(). Signed-off-by: Kai Vehmanen --- src/ipc/ipc-common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ipc/ipc-common.c b/src/ipc/ipc-common.c index b3dea0ce0021..1a17da850c7d 100644 --- a/src/ipc/ipc-common.c +++ b/src/ipc/ipc-common.c @@ -362,7 +362,17 @@ void z_vrfy_ipc_msg_list_remove(struct ipc_msg *msg) break; } } - K_OOPS(K_SYSCALL_VERIFY(found)); + + /* + * ipc_msg_list_remove() is normally called from ipc_msg_free() to drop + * a message that may or may not still be queued. A message that has + * already been sent (or was never queued) has a self-linked, empty list + * node, so removing it via list_item_del() is a harmless no-op that only + * touches &msg->list, which was already validated above. Only reject a + * non-empty node that is not on ipc->msg_list, i.e. one whose list + * pointers would make list_item_del() corrupt unrelated memory. + */ + K_OOPS(K_SYSCALL_VERIFY(found || list_is_empty(&msg->list))); z_impl_ipc_msg_list_remove(msg); } #include