mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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>
This commit is contained in:
commit
5715a50244
@ -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)
|
static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct fdp_nci_info *info = nci_get_drvdata(ndev);
|
struct fdp_nci_info *info = nci_get_drvdata(ndev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (atomic_dec_and_test(&info->data_pkt_counter))
|
if (atomic_dec_and_test(&info->data_pkt_counter))
|
||||||
info->data_pkt_counter_cb(ndev);
|
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)
|
static int fdp_nci_request_firmware(struct nci_dev *ndev)
|
||||||
|
@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
|
|||||||
ret = -EREMOTEIO;
|
ret = -EREMOTEIO;
|
||||||
} else
|
} else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
kfree_skb(skb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
if (ret) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
consume_skb(skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
|
static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
|
||||||
|
@ -80,10 +80,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
r = info->phy_ops->write(info->phy_id, skb);
|
r = info->phy_ops->write(info->phy_id, skb);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
consume_skb(skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
|
static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
|
||||||
|
@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = s3fwrn5_write(info, skb);
|
ret = s3fwrn5_write(info, skb);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
mutex_unlock(&info->mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
consume_skb(skb);
|
||||||
mutex_unlock(&info->mutex);
|
mutex_unlock(&info->mutex);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
|
static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
|
||||||
|
Loading…
Reference in New Issue
Block a user