mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 22:52:19 +02:00
wifi: ath11k: fix error path leaks in some WMI calls
This is the same pattern that was previously identified as problematic: direct 'return ath11k_wmi_cmd_send(...)' will leak the skb in the error path if it is not explicitly handled. Fixes:c417b247ba("ath11k: implement hardware data filter") Fixes:9cbd7fc9be("ath11k: support MAC address randomization in scan") Fixes:ba9177fcef("ath11k: Add basic WoW functionalities") Fixes:fec4b898f3("ath11k: Add WoW net-detect functionality") Fixes:c3c36bfe99("ath11k: support ARP and NS offload") Fixes:a16d9b50cf("ath11k: support GTK rekey offload") Fixes:652f69ed9c("ath11k: Add support for SAR") Fixes:0f84a156aa("ath11k: Handle keepalive during WoWLAN suspend and resume") Signed-off-by: Nicolas Escande <nico.escande@gmail.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com> Link: https://patch.msgid.link/20260506134240.2284016-3-nico.escande@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
55dda532bb
commit
ebad0b4899
|
|
@ -9299,7 +9299,7 @@ int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id,
|
|||
{
|
||||
struct wmi_hw_data_filter_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -9324,7 +9324,13 @@ int ath11k_wmi_hw_data_filter_cmd(struct ath11k *ar, u32 vdev_id,
|
|||
"hw data filter enable %d filter_bitmap 0x%x\n",
|
||||
enable, filter_bitmap);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_HW_DATA_FILTER_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar)
|
||||
|
|
@ -9389,7 +9395,7 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar,
|
|||
struct sk_buff *skb;
|
||||
struct wmi_scan_prob_req_oui_cmd *cmd;
|
||||
u32 prob_req_oui;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
prob_req_oui = (((u32)mac_addr[0]) << 16) |
|
||||
(((u32)mac_addr[1]) << 8) | mac_addr[2];
|
||||
|
|
@ -9408,7 +9414,13 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar,
|
|||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "scan prob req oui %d\n",
|
||||
prob_req_oui);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SCAN_PROB_REQ_OUI_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SCAN_PROB_REQ_OUI_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_SCAN_PROB_REQ_OUI_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id,
|
||||
|
|
@ -9418,6 +9430,7 @@ int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id,
|
|||
struct wmi_wow_add_del_event_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -9435,7 +9448,13 @@ int ath11k_wmi_wow_add_wakeup_event(struct ath11k *ar, u32 vdev_id,
|
|||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow add wakeup event %s enable %d vdev_id %d\n",
|
||||
wow_wakeup_event(event), enable, vdev_id);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id,
|
||||
|
|
@ -9448,6 +9467,7 @@ int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id,
|
|||
struct sk_buff *skb;
|
||||
u8 *ptr;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
sizeof(*tlv) + /* array struct */
|
||||
|
|
@ -9540,7 +9560,13 @@ int ath11k_wmi_wow_add_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id,
|
|||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow add pattern vdev_id %d pattern_id %d pattern_offset %d\n",
|
||||
vdev_id, pattern_id, pattern_offset);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_WOW_ADD_WAKE_PATTERN_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id)
|
||||
|
|
@ -9548,6 +9574,7 @@ int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id)
|
|||
struct wmi_wow_del_pattern_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -9566,7 +9593,13 @@ int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id)
|
|||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "tlv wow del pattern vdev_id %d pattern_id %d\n",
|
||||
vdev_id, pattern_id);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_WOW_DEL_WAKE_PATTERN_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
|
|
@ -9710,6 +9743,7 @@ int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id,
|
|||
struct wmi_pno_scan_req *pno_scan)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (pno_scan->enable)
|
||||
skb = ath11k_wmi_op_gen_config_pno_start(ar, vdev_id, pno_scan);
|
||||
|
|
@ -9719,7 +9753,13 @@ int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id,
|
|||
if (IS_ERR_OR_NULL(skb))
|
||||
return -ENOMEM;
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath11k_wmi_fill_ns_offload(struct ath11k *ar,
|
||||
|
|
@ -9837,6 +9877,7 @@ int ath11k_wmi_arp_ns_offload(struct ath11k *ar,
|
|||
u8 *buf_ptr;
|
||||
size_t len;
|
||||
u8 ns_cnt, ns_ext_tuples = 0;
|
||||
int ret;
|
||||
|
||||
offload = &arvif->arp_ns_offload;
|
||||
ns_cnt = offload->ipv6_count;
|
||||
|
|
@ -9875,7 +9916,13 @@ int ath11k_wmi_arp_ns_offload(struct ath11k *ar,
|
|||
if (ns_ext_tuples)
|
||||
ath11k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 1);
|
||||
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_SET_ARP_NS_OFFLOAD_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar,
|
||||
|
|
@ -9883,7 +9930,7 @@ int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar,
|
|||
{
|
||||
struct wmi_gtk_rekey_offload_cmd *cmd;
|
||||
struct ath11k_rekey_data *rekey_data = &arvif->rekey_data;
|
||||
int len;
|
||||
int ret, len;
|
||||
struct sk_buff *skb;
|
||||
__le64 replay_ctr;
|
||||
|
||||
|
|
@ -9917,14 +9964,20 @@ int ath11k_wmi_gtk_rekey_offload(struct ath11k *ar,
|
|||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "offload gtk rekey vdev: %d %d\n",
|
||||
arvif->vdev_id, enable);
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_GTK_OFFLOAD_CMDID offload\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar,
|
||||
struct ath11k_vif *arvif)
|
||||
{
|
||||
struct wmi_gtk_rekey_offload_cmd *cmd;
|
||||
int len;
|
||||
int ret, len;
|
||||
struct sk_buff *skb;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
|
@ -9941,7 +9994,13 @@ int ath11k_wmi_gtk_rekey_getinfo(struct ath11k *ar,
|
|||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "get gtk rekey vdev_id: %d\n",
|
||||
arvif->vdev_id);
|
||||
return ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_GTK_OFFLOAD_CMDID getinfo\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_val)
|
||||
|
|
@ -9951,6 +10010,7 @@ int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_va
|
|||
struct sk_buff *skb;
|
||||
u8 *buf_ptr;
|
||||
u32 len, sar_len_aligned, rsvd_len_aligned;
|
||||
int ret;
|
||||
|
||||
sar_len_aligned = roundup(BIOS_SAR_TABLE_LEN, sizeof(u32));
|
||||
rsvd_len_aligned = roundup(BIOS_SAR_RSVD1_LEN, sizeof(u32));
|
||||
|
|
@ -9981,7 +10041,13 @@ int ath11k_wmi_pdev_set_bios_sar_table_param(struct ath11k *ar, const u8 *sar_va
|
|||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned);
|
||||
|
||||
return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_BIOS_SAR_TABLE_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar)
|
||||
|
|
@ -9992,6 +10058,7 @@ int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar)
|
|||
struct sk_buff *skb;
|
||||
u8 *buf_ptr;
|
||||
u32 len, rsvd_len_aligned;
|
||||
int ret;
|
||||
|
||||
rsvd_len_aligned = roundup(BIOS_SAR_RSVD2_LEN, sizeof(u32));
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + rsvd_len_aligned;
|
||||
|
|
@ -10011,7 +10078,13 @@ int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar)
|
|||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, rsvd_len_aligned);
|
||||
|
||||
return ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_BIOS_GEO_TABLE_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_sta_keepalive(struct ath11k *ar,
|
||||
|
|
@ -10022,6 +10095,7 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar,
|
|||
struct wmi_sta_keepalive_arp_resp *arp;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*arp);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
|
|
@ -10053,7 +10127,13 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar,
|
|||
"sta keepalive vdev %d enabled %d method %d interval %d\n",
|
||||
arg->vdev_id, arg->enabled, arg->method, arg->interval);
|
||||
|
||||
return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_STA_KEEPALIVE_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user