From 0529a7adf3421acf251355444a012073abaffebc Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 2 Jul 2014 09:03:49 -0700 Subject: NFC: digital: Clear poll_tech_count before activating target Currently, digital_target_found() has a race between the events started by calling nfc_targets_found() (which ultimately expect ddev->poll_tech_count to be zero) and setting ddev->poll_tech_count to zero after the call to nfc_targets_found(). When the race is "lost" (i.e., ddev->poll_tech_count is found to not be zero by the events started by nfc_targets_found()), an error message is printed and the target is not found. A similar race exists when digital_tg_recv_atr_req() calls nfc_tm_activated(). Fix this by first saving the current value of ddev->poll_tech_count and then clearing it before calling nfc_targets_found()/nfc_tm_activated(). Clearing ddev->poll_tech_count before calling nfc_targets_found()/nfc_tm_activated() eliminates the race. Saving the value is required so it can be restored when nfc_targets_found()/nfc_tm_activated() fails and polling needs to continue. Acked-by: Thierry Escande Signed-off-by: Mark A. Greer Signed-off-by: Samuel Ortiz --- net/nfc/digital_core.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'net/nfc/digital_core.c') diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index a6ce3c627e4e..361bc37d2db1 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c @@ -299,6 +299,7 @@ int digital_target_found(struct nfc_digital_dev *ddev, int rc; u8 framing; u8 rf_tech; + u8 poll_tech_count; int (*check_crc)(struct sk_buff *skb); void (*add_crc)(struct sk_buff *skb); @@ -375,12 +376,16 @@ int digital_target_found(struct nfc_digital_dev *ddev, return rc; target->supported_protocols = (1 << protocol); - rc = nfc_targets_found(ddev->nfc_dev, target, 1); - if (rc) - return rc; + poll_tech_count = ddev->poll_tech_count; ddev->poll_tech_count = 0; + rc = nfc_targets_found(ddev->nfc_dev, target, 1); + if (rc) { + ddev->poll_tech_count = poll_tech_count; + return rc; + } + return 0; } -- cgit v1.2.3