kernel: poll: patch recursive lock in z_vrfy_k_poll
In z_vrfy_k_poll, there is a memory access check K_SYSCALL_MEMORY_WRITE which is wrapped in a spinlock, the same spinlock used in z_handle_obj_poll_events which is called from k_sem_give() for example. The K_SYSCALL_MEMORY_WRITE() macro conditionally calls LOG_ERR() which may call the UART console, which may call an API like k_sem_give(). This will cause a deadlock since the locked spinlock will be relocked, and a recursive lock if SPINLOCK_VALIDATE and ASSERTS are enabled as the validation will fail, causing a LOG_ERR, causing a k_sem_give() causing a relock... until stack overflows. To solve the issue, only protect the copy of events to events_copy with the spinlock, the content of events is not actually checked, and bound is not shared, so there is no need to do this validation in a critical section. The contents of events is shared so that must be copied in atomically. Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
This commit is contained in:
committed by
Maureen Helm
parent
ce526f2e16
commit
6e4ef44847
@@ -376,11 +376,11 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events,
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
if (K_SYSCALL_MEMORY_WRITE(events, bounds)) {
|
||||
k_spin_unlock(&lock, key);
|
||||
goto oops_free;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
(void)memcpy(events_copy, events, bounds);
|
||||
k_spin_unlock(&lock, key);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user