summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2022-10-31 00:43:26 +0300
committerDavid S. Miller <davem@davemloft.net>2022-10-31 00:43:26 +0300
commit5715a502447b07f067ee5af36465c7c2b813ff38 (patch)
tree358abf6f470edc7dc072ccf4eb9782448606d4d9 /drivers
parenta2c65a9d0568b6737c02b54f00b80716a53fac61 (diff)
parent93d904a734a74c54d945a9884b4962977f1176cd (diff)
downloadlinux-5715a502447b07f067ee5af36465c7c2b813ff38.tar.xz
Merge branch 'nfc-skb-leaks'
Shang XiaoJing says: ==================== nfc: Fix potential memory leak of skb There are 6 kinds of send functions can be called by nci_send_frame(): virtual_nci_send(), fdp_nci_send(), nxp_nci_send(), s3fwrn5_nci_send(), nfcmrvl_nci_send(), st_nci_send(); 1. virtual_nci_send() will memleak the skb, and has been fixed before. 2. fdp_nci_send() won't free the skb no matter whether write() succeed. 3-4. nxp_nci_send() and s3fwrn5_nci_send() will only free the skb when write() failed, however write() will not free the skb by itself for when succeeds. 5. nfcmrvl_nci_send() will call nfcmrvl_XXX_nci_send(), where some of them will free the skb, but nfcmrvl_i2c_nci_send() only free the skb when i2c_master_send() return >=0, and memleak will happen when i2c_master_send() failed in nfcmrvl_i2c_nci_send(). 6. st_nci_send() will queue the skb into other list and finally be freed. Fix the potential memory leak of skb. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nfc/fdp/fdp.c10
-rw-r--r--drivers/nfc/nfcmrvl/i2c.c7
-rw-r--r--drivers/nfc/nxp-nci/core.c7
-rw-r--r--drivers/nfc/s3fwrn5/core.c8
4 files changed, 26 insertions, 6 deletions
diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c
index c6b3334f24c9..f12f903a9dd1 100644
--- a/drivers/nfc/fdp/fdp.c
+++ b/drivers/nfc/fdp/fdp.c
@@ -249,11 +249,19 @@ static int fdp_nci_close(struct nci_dev *ndev)
static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
{
struct fdp_nci_info *info = nci_get_drvdata(ndev);
+ int ret;
if (atomic_dec_and_test(&info->data_pkt_counter))
info->data_pkt_counter_cb(ndev);
- return info->phy_ops->write(info->phy, skb);
+ ret = info->phy_ops->write(info->phy, skb);
+ if (ret < 0) {
+ kfree_skb(skb);
+ return ret;
+ }
+
+ consume_skb(skb);
+ return 0;
}
static int fdp_nci_request_firmware(struct nci_dev *ndev)
diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
index acef0cfd76af..24436c9e54c9 100644
--- a/drivers/nfc/nfcmrvl/i2c.c
+++ b/drivers/nfc/nfcmrvl/i2c.c
@@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
ret = -EREMOTEIO;
} else
ret = 0;
+ }
+
+ if (ret) {
kfree_skb(skb);
+ return ret;
}
- return ret;
+ consume_skb(skb);
+ return 0;
}
static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c
index 7c93d484dc1b..580cb6ecffee 100644
--- a/drivers/nfc/nxp-nci/core.c
+++ b/drivers/nfc/nxp-nci/core.c
@@ -80,10 +80,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
return -EINVAL;
r = info->phy_ops->write(info->phy_id, skb);
- if (r < 0)
+ if (r < 0) {
kfree_skb(skb);
+ return r;
+ }
- return r;
+ consume_skb(skb);
+ return 0;
}
static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c
index 1c412007fabb..0270e05b68df 100644
--- a/drivers/nfc/s3fwrn5/core.c
+++ b/drivers/nfc/s3fwrn5/core.c
@@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
}
ret = s3fwrn5_write(info, skb);
- if (ret < 0)
+ if (ret < 0) {
kfree_skb(skb);
+ mutex_unlock(&info->mutex);
+ return ret;
+ }
+ consume_skb(skb);
mutex_unlock(&info->mutex);
- return ret;
+ return 0;
}
static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)