net: sockets: socketpair: fix locking
The irq_lock() usage here is incompatible with SMP systems, and one's first reaction might be to convert it to a spinlock. But are those irq_lock() instances really necessary? Commit 6161ea25 ("net: socket: socketpair: mitigate possible race condition") doesn't say much: > There was a possible race condition between sock_is_nonblock() > and k_sem_take() in spair_read() and spair_write() that was > mitigated. A possible race without the irq_lock would be: thread A thread B | | + spair_write(): | + is_nonblock = sock_is_nonblock(spair); [false] * [preemption here] | | + spair_ioctl(): | + res = k_sem_take(&spair->sem, K_FOREVER); | + [...] | + spair->flags |= SPAIR_FLAG_NONBLOCK; | * [preemption here] + res = k_sem_take(&spair->sem, K_NO_WAIT); [-1] + if (res < 0) { | + if (is_nonblock) { [skipped] } * res = k_sem_take(&spair->sem, K_FOREVER); [blocks here] | + [...] But the version with irq_lock() isn't much better: thread A thread B | | | + spair_ioctl(): | + res = k_sem_take(&spair->sem, K_FOREVER); | + [...] | * [preemption here] + spair_write(): | + irq_lock(); | + is_nonblock = sock_is_nonblock(spair); [false] + res = k_sem_take(&spair->sem, K_NO_WAIT); [-1] + irq_unlock(); | * [preemption here] | | + spair->flags |= SPAIR_FLAG_NONBLOCK; | + [...] | + k_sem_give(&spair->sem); | + spair_read(): | + res = k_sem_take(&spair->sem, K_NO_WAIT); | * [preemption here] + if (res < 0) { | + if (is_nonblock) { [skipped] } * res = k_sem_take(&spair->sem, K_FOREVER); [blocks here] In both cases the last k_sem_take(K_FOREVER) will block despite SPAIR_FLAG_NONBLOCK being set at that moment. Other race scenarios exist too, and on SMP they are even more likely. The only guarantee provided by the irq_lock() is to make sure that whenever the semaphore is acquired then the is_nonblock value is always current. A better way to achieve that and be SMP compatible is to simply move the initial sock_is_nonblock() *after* the k_sem_take() and remove those irq_locks(). Signed-off-by:Nicolas Pitre <npitre@baylibre.com>
Loading
Please sign in to comment