From f2bec47224fb48feb071ad79f53ad3afccff9109 Mon Sep 17 00:00:00 2001 From: Sarada Prasanna Garnayak Date: Tue, 28 Nov 2017 12:24:39 +0530 Subject: [PATCH] ath10k: fix the potential buffer overflow in wow offload Update the arp and ns tuple for arp-ns tlv cmd and pass the size of IP address and wlan net dev name during mem copy and comparison. CRs-Fixed: 2149966 Change-Id: I9457af4578c70f876c3a58e3d8c655dcaa476e07 Signed-off-by: Sarada Prasanna Garnayak --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 19 ++++++++++--------- drivers/net/wireless/ath/ath10k/wow.c | 5 +++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index b904a0d9d391..aeeccade58b9 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3020,8 +3020,8 @@ ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar, void *ptr; int i; struct wmi_ns_arp_offload_req *arp = &arvif->arp_offload; - struct wmi_ns_offload *ns_tuple[WMI_MAX_NS_OFFLOADS]; - struct wmi_arp_offload *arp_tuple[WMI_MAX_ARP_OFFLOADS]; + struct wmi_ns_offload *ns_tuple; + struct wmi_arp_offload *arp_tuple; len = sizeof(*cmd) + sizeof(*tlv) + sizeof(*tlv) + WMI_MAX_NS_OFFLOADS * @@ -3052,8 +3052,8 @@ ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar, for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_ns_offload)); - ns_tuple[i] = (struct wmi_ns_offload *)tlv->value; - ns_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); + ns_tuple = (struct wmi_ns_offload *)tlv->value; + ns_tuple->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); ptr += (sizeof(*tlv) + sizeof(struct wmi_ns_offload)); tlv = ptr; } @@ -3067,14 +3067,15 @@ ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar, for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_arp_offload)); - arp_tuple[i] = (struct wmi_arp_offload *)tlv->value; + arp_tuple = (struct wmi_arp_offload *)tlv->value; if (arp->enable_offload && (i == 0)) { - arp_tuple[i]->flags |= + arp_tuple->flags |= __cpu_to_le32(WMI_ARPOFF_FLAGS_VALID); - memcpy(&arp_tuple[i]->target_ipaddr, - &arp->params.ipv4_addr, 4); + memcpy(&arp_tuple->target_ipaddr, + &arp->params.ipv4_addr, + sizeof(arp_tuple->target_ipaddr)); } else { - arp_tuple[i]->flags |= + arp_tuple->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); } ptr += (sizeof(*tlv) + sizeof(struct wmi_arp_offload)); diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c index 1a43375c3264..429fcce3dd1e 100644 --- a/drivers/net/wireless/ath/ath10k/wow.c +++ b/drivers/net/wireless/ath/ath10k/wow.c @@ -251,7 +251,7 @@ ath10k_wow_fill_vdev_arp_offload_struct(struct ath10k_vif *arvif, arp->offload_type = __cpu_to_le16(WMI_IPV4_ARP_REPLY_OFFLOAD); arp->enable_offload = __cpu_to_le16(WMI_ARP_NS_OFFLOAD_ENABLE); for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { - if (!strcmp(ifa->ifa_label, wdev->netdev->name)) { + if (!memcmp(ifa->ifa_label, wdev->netdev->name, IFNAMSIZ)) { offload_params_found = true; break; } @@ -259,8 +259,9 @@ ath10k_wow_fill_vdev_arp_offload_struct(struct ath10k_vif *arvif, if (!offload_params_found) return -ENODEV; + memcpy(&arp->params.ipv4_addr, &ifa->ifa_local, + sizeof(arp->params.ipv4_addr)); - memcpy(&arp->params.ipv4_addr, &ifa->ifa_local, 4); return 0; }