Potential Race Condition in tls_hw_hash() and alike

From: Navid Emamdoost
Date: Mon May 04 2020 - 18:45:06 EST


Hi,

I was wondering if a race condition in net/tls/tls_main.c may lead to
a UAF or not?

The scenario can be like this:
1) device is initialized and registered via chtls_register_dev()
2) while tls_hw_hash() is executed in one thread, the device gets
detached (CPU2), and another thread tries to acquire the pointer
(CPU3):

CPU1: tls_hw_hash()
CPU2: chtls_uld_state_change()
CPU3: can be tls_hw_hash() or tls_hw_unhash()
//<assume kref == 1>
spin_lock_bh(&device_spinlock);
list_for_each_entry(dev, &device_list, dev_list) {
if (dev->hash) {
kref_get(&dev->kref); //kref == 2
spin_unlock_bh(&device_spinlock);
kref_put(&cdev->tlsdev.kref, cdev->tlsdev.release); //kref == 1
err |= dev->hash(dev, sk);


spin_lock_bh(&device_spinlock);
kref_put(&dev->kref, dev->release); //kref
== 0, release
kref_get(&dev->kref); //BUG: kref 0 to 1!




Basically, the problem comes from the fact that kref_put is not lock protected.
Do you agree that such a race condition may happen? If yes, then is
moving kref_put inside the lock a practical solution?

Thank you,
--
Navid.