Skip to content

Commit

Permalink
NFC: reorganize the functions in nci_request
Browse files Browse the repository at this point in the history
There is a possible data race as shown below:

thread-A in nci_request()       | thread-B in nci_close_device()
                                | mutex_lock(&ndev->req_lock);
test_bit(NCI_UP, &ndev->flags); |
...                             | test_and_clear_bit(NCI_UP, &ndev->flags)
mutex_lock(&ndev->req_lock);    |
                                |

This race will allow __nci_request() to be awaked while the device is
getting removed.

Similar to commit e2cb6b8 ("bluetooth: eliminate the potential race
condition when removing the HCI controller"). this patch alters the
function sequence in nci_request() to prevent the data races between the
nci_close_device().

Signed-off-by: Lin Ma <linma@zju.edu.cn>
Fixes: 6a2968a ("NFC: basic NCI protocol implementation")
Link: https://lore.kernel.org/r/20211115145600.8320-1-linma@zju.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
f0rm2l1n authored and kuba-moo committed Nov 18, 2021
1 parent 3e6db07 commit 86cdf8e
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions net/nfc/nci/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,15 @@ inline int nci_request(struct nci_dev *ndev,
{
int rc;

if (!test_bit(NCI_UP, &ndev->flags))
return -ENETDOWN;

/* Serialize all requests */
mutex_lock(&ndev->req_lock);
rc = __nci_request(ndev, req, opt, timeout);
/* check the state after obtaing the lock against any races
* from nci_close_device when the device gets removed.
*/
if (test_bit(NCI_UP, &ndev->flags))
rc = __nci_request(ndev, req, opt, timeout);
else
rc = -ENETDOWN;
mutex_unlock(&ndev->req_lock);

return rc;
Expand Down

0 comments on commit 86cdf8e

Please sign in to comment.