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:
Bjarki Arge Andreasen
2025-12-16 14:43:16 +01:00
committed by Maureen Helm
parent ce526f2e16
commit 6e4ef44847

View File

@@ -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);