From 90045619d3df85fcf9b90ae64a2ad9221af2113a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2021 10:46:12 +0200 Subject: [PATCH] ll-scheduler: only modify the task if it is valid schedule_ll_task_cancel() looks for a task on the list to cancel it. However, if it doesn't find the task on the list it still sets its status and deletes it from the list. Currently this doesn't cause any problems, but it's potentially dangerous. This function can be called for completed tasks, which are no longer on the list. So list_item_del() will be called for the second time for it. Currently this isn't a problem because SOF implementation of that function also initialises the list head, but not all doubly-linked list implementations do that. E.g. Zephyr's sys_dlist_remove() nullifies both .next and .prev, so, a repeated call to it would cause a NULL dereference. In general it's safer to only modify an element when it has been verified to be valid. Signed-off-by: Guennadi Liakhovetski --- src/schedule/ll_schedule.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 5640bf30d..81e16c9c7 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -537,14 +537,15 @@ static int schedule_ll_task_cancel(void *data, struct task *task) /* found it */ if (curr_task == task) { schedule_ll_domain_clear(sch, task); + + /* remove work from list */ + task->state = SOF_TASK_STATE_CANCEL; + list_item_del(&task->list); + break; } } - /* remove work from list */ - task->state = SOF_TASK_STATE_CANCEL; - list_item_del(&task->list); - irq_local_enable(flags); return 0;