Skip to content

Commit 86bd911

Browse files
committed
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: <err> os.z_vrfy_ipc_msg_list_remove: syscall z_vrfy_ipc_msg_list_remove ... failed check: found <err> 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 <kai.vehmanen@linux.intel.com>
1 parent e8fafe2 commit 86bd911

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

src/ipc/ipc-common.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,17 @@ void z_vrfy_ipc_msg_list_remove(struct ipc_msg *msg)
362362
break;
363363
}
364364
}
365-
K_OOPS(K_SYSCALL_VERIFY(found));
365+
366+
/*
367+
* ipc_msg_list_remove() is normally called from ipc_msg_free() to drop
368+
* a message that may or may not still be queued. A message that has
369+
* already been sent (or was never queued) has a self-linked, empty list
370+
* node, so removing it via list_item_del() is a harmless no-op that only
371+
* touches &msg->list, which was already validated above. Only reject a
372+
* non-empty node that is not on ipc->msg_list, i.e. one whose list
373+
* pointers would make list_item_del() corrupt unrelated memory.
374+
*/
375+
K_OOPS(K_SYSCALL_VERIFY(found || list_is_empty(&msg->list)));
366376
z_impl_ipc_msg_list_remove(msg);
367377
}
368378
#include <zephyr/syscalls/ipc_msg_list_remove_mrsh.c>

0 commit comments

Comments
 (0)