From e530d198bdbfe59b5c99ee48287e81f893326731 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 30 Jan 2018 15:33:59 +0000 Subject: NFC: fdp: fix signed less or equal zero check in u8 max_size The u8 variable max_size is being assigned a return value from the call to nci_conn_max_data_pkt_payload_size that can return a -ve error return. Since max_size is a u8, the -ve check for the error will always be false. Fix this by making max_size an int type. Detected using Coccinelle: drivers/nfc/fdp/fdp.c:208:5-13: WARNING: Unsigned expression compared with zero: max_size <= 0 Fixes: a06347c04c13 ("NFC: Add Intel Fields Peak NFC solution driver") Signed-off-by: Colin Ian King Signed-off-by: Samuel Ortiz --- drivers/nfc/fdp/fdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index d5784a47fc13..5ddc01b4913a 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c @@ -192,8 +192,8 @@ static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type) const struct firmware *fw; struct sk_buff *skb; unsigned long len; - u8 max_size, payload_size; - int rc = 0; + u8 payload_size; + int max_size, rc = 0; if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) || (type == NCI_PATCH_TYPE_RAM && !info->ram_patch)) -- cgit v1.2.1 From 6a893401a728236d9bec0575d73527992ca7929c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 24 Mar 2018 10:44:58 -0300 Subject: nfc: st21nfca: Check for devm_kzalloc() failure devm_kzalloc() may fail, so we should better check for error and propagate the error in the case of allocation failure. This avoids a potential NULL pointer dereference later on. Signed-off-by: Fabio Estevam Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/se.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/nfc') diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index 4bed9e842db3..fd967a38a94a 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -328,6 +328,8 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); + if (!transaction) + return -ENOMEM; transaction->aid_len = skb->data[1]; memcpy(transaction->aid, &skb->data[2], -- cgit v1.2.1 From 4e4e8232f0ae36573a66f40c765198baa75f327b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 24 Mar 2018 10:44:59 -0300 Subject: nfc: st21nfca: Remove unnecessary devm_kzalloc() cast There is no need to use cast for the returned value from memory allocation functions, so remove the unnecessary cast. Detected via Coccinelle script: scripts/coccinelle/api/alloc/alloc_cast.cocci. Signed-off-by: Fabio Estevam Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/se.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index fd967a38a94a..5b63549bf76a 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -326,8 +326,7 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; - transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev, - skb->len - 2, GFP_KERNEL); + transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); if (!transaction) return -ENOMEM; -- cgit v1.2.1 From 85ef4f34cc64ecd13099817bbcab0b46564f7413 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 16 May 2018 15:32:46 +0200 Subject: NFC: st95hf: initialize semaphore and mutex earlier 'rm_lock' and 'exchange_lock' need to be ready before the IRQ handler has a chance to fire. This fixes the oops below. [ 1.040255] Internal error: Oops: 96000004 [#1] PREEMPT SMP [...] [ 1.181564] Call trace: [ 1.188591] Exception stack(0xffff00000a473c40 to 0xffff00000a473d80) [ 1.190943] 3c40: ffff80003673b118 0000000000000000 ffff800036374380 0000000000000000 [ 1.197542] 3c60: 0000000000000000 0000000000000000 00000000044b2ac5 0000000000000001 [ 1.205354] 3c80: ffff800036374d60 ffff00000a473d70 0000000000000980 0000000000000000 [ 1.213166] 3ca0: 0000000000000001 0000000000000000 000000000000004c 0000000000000033 [ 1.217590] st95hf spi2.0: err: por seq failed for st95hf [ 1.228788] 3cc0: 0000000000000019 0000000000000001 0000000000000007 ffff80003673b118 [ 1.234175] 3ce0: ffff800009f27000 0000000000000000 ffff80003673b1c8 ffff80003673b1b0 [ 1.241986] 3d00: ffff0000080f0000 ffff800009f716a4 ffff00000894bb40 0000000000000000 [ 1.249800] 3d20: 0000000000000000 ffff00000a473d80 ffff0000084268c0 ffff00000a473d80 [ 1.257611] 3d40: ffff0000084268c4 0000000040000005 ffff00000a473d60 ffff0000080e5688 [ 1.265424] 3d60: ffffffffffffffff ffff0000084268a4 ffff00000a473d80 ffff0000084268c4 [ 1.273239] [] st95hf_irq_thread_handler+0x44/0x3a0 [ 1.281048] [] irq_thread_fn+0x28/0x68 [ 1.287468] [] irq_thread+0x10c/0x1a0 [ 1.292850] [] kthread+0x12c/0x130 [ 1.297799] [] ret_from_fork+0x10/0x18 [ 1.303008] Code: aa1603e0 f9403675 940d010f aa1303e0 (f94066a1) [ 1.308307] ---[ end trace d058c1b88aad74d8 ]--- Signed-off-by: Daniel Mack Signed-off-by: Samuel Ortiz --- drivers/nfc/st95hf/core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c index 2b26f762fbc3..394bdc7b0cf2 100644 --- a/drivers/nfc/st95hf/core.c +++ b/drivers/nfc/st95hf/core.c @@ -1112,8 +1112,10 @@ static int st95hf_probe(struct spi_device *nfc_spi_dev) } } + sema_init(&st95context->exchange_lock, 1); init_completion(&spicontext->done); mutex_init(&spicontext->spi_lock); + mutex_init(&st95context->rm_lock); /* * Store spicontext in spi device object for using it in @@ -1197,9 +1199,6 @@ static int st95hf_probe(struct spi_device *nfc_spi_dev) /* store st95context in nfc device object */ nfc_digital_set_drvdata(st95context->ddev, st95context); - sema_init(&st95context->exchange_lock, 1); - mutex_init(&st95context->rm_lock); - return ret; err_free_digital_device: -- cgit v1.2.1 From c99f996b2ba49572d228075a5517455b8ecf6585 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 16 May 2018 15:32:47 +0200 Subject: NFC: st95hf: drop illegal kfree_skb() The skb that is passed in to ->in_send_cmd() is freed by the core when the function returns. Calling kfree_skb() on it from the driver callback will hence lead to a double-free. Signed-off-by: Daniel Mack Signed-off-by: Samuel Ortiz --- drivers/nfc/st95hf/core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c index 394bdc7b0cf2..a50a95cfcfd8 100644 --- a/drivers/nfc/st95hf/core.c +++ b/drivers/nfc/st95hf/core.c @@ -995,8 +995,6 @@ static int st95hf_in_send_cmd(struct nfc_digital_dev *ddev, goto free_skb_resp; } - kfree_skb(skb); - return rc; free_skb_resp: -- cgit v1.2.1 From 48badd41fbfd803331dc8796cbb12b826a6446b9 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Fri, 4 May 2018 00:08:53 +0530 Subject: NFC: st21nfca: Fix out of bounds kernel access when handling ATR_REQ Out of bounds kernel accesses in st21nfca's NFC HCI layer might happen when handling ATR_REQ events if user-specified atr_req->length is bigger than the buffer size. In that case memcpy() inside st21nfca_tm_send_atr_res() will read extra bytes resulting in OOB read from the kernel heap. cc: Stable Signed-off-by: Suren Baghdasaryan Signed-off-by: Amit Pundir Reviewed-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfca/dep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/st21nfca/dep.c b/drivers/nfc/st21nfca/dep.c index fd08be2917e6..3420c5104c94 100644 --- a/drivers/nfc/st21nfca/dep.c +++ b/drivers/nfc/st21nfca/dep.c @@ -217,7 +217,8 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev, atr_req = (struct st21nfca_atr_req *)skb->data; - if (atr_req->length < sizeof(struct st21nfca_atr_req)) { + if (atr_req->length < sizeof(struct st21nfca_atr_req) || + atr_req->length > skb->len) { r = -EPROTO; goto exit; } -- cgit v1.2.1 From 430c62fa23d4806488cf7d4a226a4638f1945363 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Fri, 4 May 2018 00:08:55 +0530 Subject: NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver Possible buffer overflow when reading next_read_size bytes into tmp buffer after next_read_size was extracted from a previous packet. cc: Stable Signed-off-by: Suren Baghdasaryan Signed-off-by: Amit Pundir Reviewed-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/fdp/i2c.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/nfc') diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index c4da50e07bbc..2c5ed2224c5e 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -176,6 +176,15 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb) /* Packet that contains a length */ if (tmp[0] == 0 && tmp[1] == 0) { phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3; + /* + * Ensure next_read_size does not exceed sizeof(tmp) + * for reading that many bytes during next iteration + */ + if (phy->next_read_size > FDP_NCI_I2C_MAX_PAYLOAD) { + dev_dbg(&client->dev, "corrupted packet\n"); + phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD; + goto flush; + } } else { phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD; -- cgit v1.2.1 From 7579d009c4a1e01d0c21e72ee9c4dbf0832f83f3 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Fri, 4 May 2018 00:08:56 +0530 Subject: NFC: fdp: Remove __func__ from dev_dbg() Remove redundant __func__ parameter from dev_dgb() calls and delete empty dev_dbg() trace calls, which are redundant if function tracer is enabled. Signed-off-by: Amit Pundir Reviewed-by: Andy Shevchenko Signed-off-by: Samuel Ortiz --- drivers/nfc/fdp/fdp.c | 18 +++--------------- drivers/nfc/fdp/i2c.c | 17 ++++------------- 2 files changed, 7 insertions(+), 28 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index 5ddc01b4913a..36d1091d288a 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c @@ -249,8 +249,6 @@ static int fdp_nci_open(struct nci_dev *ndev) struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); - r = info->phy_ops->enable(info->phy); return r; @@ -261,7 +259,6 @@ static int fdp_nci_close(struct nci_dev *ndev) struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); return 0; } @@ -270,8 +267,6 @@ static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); - if (atomic_dec_and_test(&info->data_pkt_counter)) info->data_pkt_counter_cb(ndev); @@ -283,7 +278,6 @@ int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb) struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); return nci_recv_frame(ndev, skb); } EXPORT_SYMBOL(fdp_nci_recv_frame); @@ -498,8 +492,6 @@ static int fdp_nci_setup(struct nci_dev *ndev) int r; u8 patched = 0; - dev_dbg(dev, "%s\n", __func__); - r = nci_core_init(ndev); if (r) goto error; @@ -609,7 +601,6 @@ static int fdp_nci_core_reset_ntf_packet(struct nci_dev *ndev, struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); info->setup_reset_ntf = 1; wake_up(&info->setup_wq); @@ -622,7 +613,6 @@ static int fdp_nci_prop_patch_ntf_packet(struct nci_dev *ndev, struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); info->setup_patch_ntf = 1; info->setup_patch_status = skb->data[0]; wake_up(&info->setup_wq); @@ -637,7 +627,7 @@ static int fdp_nci_prop_patch_rsp_packet(struct nci_dev *ndev, struct device *dev = &info->phy->i2c_dev->dev; u8 status = skb->data[0]; - dev_dbg(dev, "%s: status 0x%x\n", __func__, status); + dev_dbg(dev, "status 0x%x\n", status); nci_req_complete(ndev, status); return 0; @@ -650,7 +640,7 @@ static int fdp_nci_prop_set_production_data_rsp_packet(struct nci_dev *ndev, struct device *dev = &info->phy->i2c_dev->dev; u8 status = skb->data[0]; - dev_dbg(dev, "%s: status 0x%x\n", __func__, status); + dev_dbg(dev, "status 0x%x\n", status); nci_req_complete(ndev, status); return 0; @@ -695,7 +685,7 @@ static int fdp_nci_core_get_config_rsp_packet(struct nci_dev *ndev, dev_dbg(dev, "OTP version %d\n", info->otp_version); dev_dbg(dev, "RAM version %d\n", info->ram_version); dev_dbg(dev, "key index %d\n", info->key_index); - dev_dbg(dev, "%s: status 0x%x\n", __func__, rsp->status); + dev_dbg(dev, "status 0x%x\n", rsp->status); nci_req_complete(ndev, rsp->status); @@ -798,8 +788,6 @@ void fdp_nci_remove(struct nci_dev *ndev) struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - dev_dbg(dev, "%s\n", __func__); - nci_unregister_device(ndev); nci_free_device(ndev); } diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index 2c5ed2224c5e..bb14d30c568c 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -57,7 +57,6 @@ static int fdp_nci_i2c_enable(void *phy_id) { struct fdp_i2c_phy *phy = phy_id; - dev_dbg(&phy->i2c_dev->dev, "%s\n", __func__); fdp_nci_i2c_reset(phy); return 0; @@ -67,7 +66,6 @@ static void fdp_nci_i2c_disable(void *phy_id) { struct fdp_i2c_phy *phy = phy_id; - dev_dbg(&phy->i2c_dev->dev, "%s\n", __func__); fdp_nci_i2c_reset(phy); } @@ -113,8 +111,8 @@ static int fdp_nci_i2c_write(void *phy_id, struct sk_buff *skb) } if (r < 0 || r != skb->len) - dev_dbg(&client->dev, "%s: error err=%d len=%d\n", - __func__, r, skb->len); + dev_dbg(&client->dev, "error err=%d len=%d\n", + r, skb->len); if (r >= 0) { if (r != skb->len) { @@ -152,8 +150,7 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb) r = i2c_master_recv(client, tmp, len); if (r != len) { - dev_dbg(&client->dev, "%s: i2c recv err: %d\n", - __func__, r); + dev_dbg(&client->dev, "i2c recv err: %d\n", r); goto flush; } @@ -167,8 +164,7 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb) * and force resynchronization */ if (lrc) { - dev_dbg(&client->dev, "%s: corrupted packet\n", - __func__); + dev_dbg(&client->dev, "corrupted packet\n"); phy->next_read_size = 5; goto flush; } @@ -224,7 +220,6 @@ static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id) } client = phy->i2c_dev; - dev_dbg(&client->dev, "%s\n", __func__); r = fdp_nci_i2c_read(phy, &skb); @@ -305,8 +300,6 @@ static int fdp_nci_i2c_probe(struct i2c_client *client) u32 clock_freq; int r = 0; - dev_dbg(dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { nfc_err(dev, "No I2C_FUNC_I2C support\n"); return -ENODEV; @@ -368,8 +361,6 @@ static int fdp_nci_i2c_remove(struct i2c_client *client) { struct fdp_i2c_phy *phy = i2c_get_clientdata(client); - dev_dbg(&client->dev, "%s\n", __func__); - fdp_nci_remove(phy->ndev); fdp_nci_i2c_disable(phy); -- cgit v1.2.1 From 1f008cfec5d529b30ca8da1a1f5fbbd457c10382 Mon Sep 17 00:00:00 2001 From: Amit Pundir Date: Tue, 12 Jun 2018 19:44:10 +0530 Subject: NFC: fdp: Fix unused variable warnings Fix unused variable warnings reported on next-20180612. Fixes: 7579d009c4a1 ("NFC: fdp: Remove __func__ from dev_dbg()") Signed-off-by: Amit Pundir Signed-off-by: Samuel Ortiz --- drivers/nfc/fdp/fdp.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index 36d1091d288a..6b5aba8c8937 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c @@ -247,7 +247,6 @@ static int fdp_nci_open(struct nci_dev *ndev) { int r; struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; r = info->phy_ops->enable(info->phy); @@ -256,16 +255,12 @@ static int fdp_nci_open(struct nci_dev *ndev) static int fdp_nci_close(struct nci_dev *ndev) { - struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; - return 0; } static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) { struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; if (atomic_dec_and_test(&info->data_pkt_counter)) info->data_pkt_counter_cb(ndev); @@ -275,9 +270,6 @@ static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb) { - struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; - return nci_recv_frame(ndev, skb); } EXPORT_SYMBOL(fdp_nci_recv_frame); @@ -599,7 +591,6 @@ static int fdp_nci_core_reset_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) { struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; info->setup_reset_ntf = 1; wake_up(&info->setup_wq); @@ -611,7 +602,6 @@ static int fdp_nci_prop_patch_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) { struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; info->setup_patch_ntf = 1; info->setup_patch_status = skb->data[0]; @@ -785,9 +775,6 @@ EXPORT_SYMBOL(fdp_nci_probe); void fdp_nci_remove(struct nci_dev *ndev) { - struct fdp_nci_info *info = nci_get_drvdata(ndev); - struct device *dev = &info->phy->i2c_dev->dev; - nci_unregister_device(ndev); nci_free_device(ndev); } -- cgit v1.2.1