mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-24 14:29:38 +07:00
ath6kl: Fix potential skb double free in ath6kl_wmi_sync_point()
skb given to ath6kl_control_tx() is owned by ath6kl_control_tx(). Calling function should not free the skb for error cases. This is found during code review. kvalo: fix a checkpatch warning in ath6kl_wmi_cmd_send() Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
f21243a822
commit
0616dc1f2b
@ -288,8 +288,10 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
struct ath6kl_cookie *cookie = NULL;
|
struct ath6kl_cookie *cookie = NULL;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
|
if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_bh(&ar->lock);
|
spin_lock_bh(&ar->lock);
|
||||||
|
|
||||||
|
@ -1739,8 +1739,11 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
|
|||||||
int ret;
|
int ret;
|
||||||
u16 info1;
|
u16 info1;
|
||||||
|
|
||||||
if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1))))
|
if (WARN_ON(skb == NULL ||
|
||||||
|
(if_idx > (wmi->parent_dev->vif_max - 1)))) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
|
ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
|
||||||
cmd_id, skb->len, sync_flag);
|
cmd_id, skb->len, sync_flag);
|
||||||
@ -2352,8 +2355,10 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
|
|||||||
struct wmi_data_hdr *data_hdr;
|
struct wmi_data_hdr *data_hdr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
|
if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
skb_push(skb, sizeof(struct wmi_data_hdr));
|
skb_push(skb, sizeof(struct wmi_data_hdr));
|
||||||
|
|
||||||
@ -2390,10 +2395,8 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
|
|||||||
spin_unlock_bh(&wmi->lock);
|
spin_unlock_bh(&wmi->lock);
|
||||||
|
|
||||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||||
if (!skb) {
|
if (!skb)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = (struct wmi_sync_cmd *) skb->data;
|
cmd = (struct wmi_sync_cmd *) skb->data;
|
||||||
|
|
||||||
@ -2416,7 +2419,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
|
|||||||
* then do not send the Synchronize cmd on the control ep
|
* then do not send the Synchronize cmd on the control ep
|
||||||
*/
|
*/
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_skb;
|
goto free_cmd_skb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send sync cmd followed by sync data messages on all
|
* Send sync cmd followed by sync data messages on all
|
||||||
@ -2426,15 +2429,12 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
|
|||||||
NO_SYNC_WMIFLAG);
|
NO_SYNC_WMIFLAG);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free_skb;
|
goto free_data_skb;
|
||||||
|
|
||||||
/* cmd buffer sent, we no longer own it */
|
|
||||||
skb = NULL;
|
|
||||||
|
|
||||||
for (index = 0; index < num_pri_streams; index++) {
|
for (index = 0; index < num_pri_streams; index++) {
|
||||||
|
|
||||||
if (WARN_ON(!data_sync_bufs[index].skb))
|
if (WARN_ON(!data_sync_bufs[index].skb))
|
||||||
break;
|
goto free_data_skb;
|
||||||
|
|
||||||
ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
|
ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
|
||||||
data_sync_bufs[index].
|
data_sync_bufs[index].
|
||||||
@ -2443,17 +2443,20 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
|
|||||||
ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
|
ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
|
||||||
ep_id, if_idx);
|
ep_id, if_idx);
|
||||||
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
data_sync_bufs[index].skb = NULL;
|
data_sync_bufs[index].skb = NULL;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
goto free_data_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_skb:
|
return 0;
|
||||||
|
|
||||||
|
free_cmd_skb:
|
||||||
/* free up any resources left over (possibly due to an error) */
|
/* free up any resources left over (possibly due to an error) */
|
||||||
if (skb)
|
if (skb)
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
|
free_data_skb:
|
||||||
for (index = 0; index < num_pri_streams; index++) {
|
for (index = 0; index < num_pri_streams; index++) {
|
||||||
if (data_sync_bufs[index].skb != NULL) {
|
if (data_sync_bufs[index].skb != NULL) {
|
||||||
dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
|
dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
|
||||||
|
Loading…
Reference in New Issue
Block a user