Commit 1b9dadba authored by Wei Yongjun's avatar Wei Yongjun Committed by David S. Miller

NFC: st21nfca: Fix memory leak in device probe and remove

'phy->pending_skb' is alloced when device probe, but forgot to free
in the error handling path and remove path, this cause memory leak
as follows:

unreferenced object 0xffff88800bc06800 (size 512):
  comm "8", pid 11775, jiffies 4295159829 (age 9.032s)
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<00000000d66c09ce>] __kmalloc_node_track_caller+0x1ed/0x450
    [<00000000c93382b3>] kmalloc_reserve+0x37/0xd0
    [<000000005fea522c>] __alloc_skb+0x124/0x380
    [<0000000019f29f9a>] st21nfca_hci_i2c_probe+0x170/0x8f2

Fix it by freeing 'pending_skb' in error and remove.

Fixes: 68957303 ("NFC: ST21NFCA: Add driver for STMicroelectronics ST21NFCA NFC Chip")
Reported-by: default avatarHulk Robot <hulkci@huawei.com>
Signed-off-by: default avatarWei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5be60a94
...@@ -524,7 +524,8 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -524,7 +524,8 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
phy->gpiod_ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); phy->gpiod_ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(phy->gpiod_ena)) { if (IS_ERR(phy->gpiod_ena)) {
nfc_err(dev, "Unable to get ENABLE GPIO\n"); nfc_err(dev, "Unable to get ENABLE GPIO\n");
return PTR_ERR(phy->gpiod_ena); r = PTR_ERR(phy->gpiod_ena);
goto out_free;
} }
phy->se_status.is_ese_present = phy->se_status.is_ese_present =
...@@ -535,7 +536,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -535,7 +536,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
r = st21nfca_hci_platform_init(phy); r = st21nfca_hci_platform_init(phy);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, "Unable to reboot st21nfca\n"); nfc_err(&client->dev, "Unable to reboot st21nfca\n");
return r; goto out_free;
} }
r = devm_request_threaded_irq(&client->dev, client->irq, NULL, r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
...@@ -544,15 +545,23 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -544,15 +545,23 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
ST21NFCA_HCI_DRIVER_NAME, phy); ST21NFCA_HCI_DRIVER_NAME, phy);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, "Unable to register IRQ handler\n"); nfc_err(&client->dev, "Unable to register IRQ handler\n");
return r; goto out_free;
} }
return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, r = st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME,
ST21NFCA_FRAME_HEADROOM, ST21NFCA_FRAME_HEADROOM,
ST21NFCA_FRAME_TAILROOM, ST21NFCA_FRAME_TAILROOM,
ST21NFCA_HCI_LLC_MAX_PAYLOAD, ST21NFCA_HCI_LLC_MAX_PAYLOAD,
&phy->hdev, &phy->hdev,
&phy->se_status); &phy->se_status);
if (r)
goto out_free;
return 0;
out_free:
kfree_skb(phy->pending_skb);
return r;
} }
static int st21nfca_hci_i2c_remove(struct i2c_client *client) static int st21nfca_hci_i2c_remove(struct i2c_client *client)
...@@ -563,6 +572,8 @@ static int st21nfca_hci_i2c_remove(struct i2c_client *client) ...@@ -563,6 +572,8 @@ static int st21nfca_hci_i2c_remove(struct i2c_client *client)
if (phy->powered) if (phy->powered)
st21nfca_hci_i2c_disable(phy); st21nfca_hci_i2c_disable(phy);
if (phy->pending_skb)
kfree_skb(phy->pending_skb);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment