| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for RNDIS based wireless USB devices. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net> |
|---|
| 5 | 6 | * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@iki.fi> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | 7 | * |
|---|
| 20 | 8 | * Portions of this file are based on NDISwrapper project, |
|---|
| 21 | 9 | * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani |
|---|
| .. | .. |
|---|
| 213 | 201 | struct ndis_80211_pmkid_cand_list { |
|---|
| 214 | 202 | __le32 version; |
|---|
| 215 | 203 | __le32 num_candidates; |
|---|
| 216 | | - struct ndis_80211_pmkid_candidate candidate_list[0]; |
|---|
| 204 | + struct ndis_80211_pmkid_candidate candidate_list[]; |
|---|
| 217 | 205 | } __packed; |
|---|
| 218 | 206 | |
|---|
| 219 | 207 | struct ndis_80211_status_indication { |
|---|
| .. | .. |
|---|
| 258 | 246 | __le32 net_infra; |
|---|
| 259 | 247 | u8 rates[NDIS_802_11_LENGTH_RATES_EX]; |
|---|
| 260 | 248 | __le32 ie_length; |
|---|
| 261 | | - u8 ies[0]; |
|---|
| 249 | + u8 ies[]; |
|---|
| 262 | 250 | } __packed; |
|---|
| 263 | 251 | |
|---|
| 264 | 252 | struct ndis_80211_bssid_list_ex { |
|---|
| 265 | 253 | __le32 num_items; |
|---|
| 266 | | - struct ndis_80211_bssid_ex bssid[0]; |
|---|
| 254 | + struct ndis_80211_bssid_ex bssid[]; |
|---|
| 267 | 255 | } __packed; |
|---|
| 268 | 256 | |
|---|
| 269 | 257 | struct ndis_80211_fixed_ies { |
|---|
| .. | .. |
|---|
| 324 | 312 | __le32 offset_resp_ies; |
|---|
| 325 | 313 | } __packed; |
|---|
| 326 | 314 | |
|---|
| 327 | | -struct ndis_80211_auth_encr_pair { |
|---|
| 328 | | - __le32 auth_mode; |
|---|
| 329 | | - __le32 encr_mode; |
|---|
| 330 | | -} __packed; |
|---|
| 331 | | - |
|---|
| 332 | 315 | struct ndis_80211_capability { |
|---|
| 333 | 316 | __le32 length; |
|---|
| 334 | 317 | __le32 version; |
|---|
| 335 | 318 | __le32 num_pmkids; |
|---|
| 336 | 319 | __le32 num_auth_encr_pair; |
|---|
| 337 | | - struct ndis_80211_auth_encr_pair auth_encr_pair[0]; |
|---|
| 338 | 320 | } __packed; |
|---|
| 339 | 321 | |
|---|
| 340 | 322 | struct ndis_80211_bssid_info { |
|---|
| .. | .. |
|---|
| 345 | 327 | struct ndis_80211_pmkid { |
|---|
| 346 | 328 | __le32 length; |
|---|
| 347 | 329 | __le32 bssid_info_count; |
|---|
| 348 | | - struct ndis_80211_bssid_info bssid_info[0]; |
|---|
| 330 | + struct ndis_80211_bssid_info bssid_info[]; |
|---|
| 349 | 331 | } __packed; |
|---|
| 350 | 332 | |
|---|
| 351 | 333 | /* |
|---|
| .. | .. |
|---|
| 712 | 694 | struct rndis_query *get; |
|---|
| 713 | 695 | struct rndis_query_c *get_c; |
|---|
| 714 | 696 | } u; |
|---|
| 715 | | - int ret, buflen; |
|---|
| 716 | | - int resplen, respoffs, copylen; |
|---|
| 697 | + int ret; |
|---|
| 698 | + size_t buflen, resplen, respoffs, copylen; |
|---|
| 717 | 699 | |
|---|
| 718 | 700 | buflen = *len + sizeof(*u.get); |
|---|
| 719 | 701 | if (buflen < CONTROL_BUFFER_SIZE) |
|---|
| .. | .. |
|---|
| 748 | 730 | |
|---|
| 749 | 731 | if (respoffs > buflen) { |
|---|
| 750 | 732 | /* Device returned data offset outside buffer, error. */ |
|---|
| 751 | | - netdev_dbg(dev->net, "%s(%s): received invalid " |
|---|
| 752 | | - "data offset: %d > %d\n", __func__, |
|---|
| 753 | | - oid_to_string(oid), respoffs, buflen); |
|---|
| 733 | + netdev_dbg(dev->net, |
|---|
| 734 | + "%s(%s): received invalid data offset: %zu > %zu\n", |
|---|
| 735 | + __func__, oid_to_string(oid), respoffs, buflen); |
|---|
| 754 | 736 | |
|---|
| 755 | 737 | ret = -EINVAL; |
|---|
| 756 | 738 | goto exit_unlock; |
|---|
| 757 | 739 | } |
|---|
| 758 | 740 | |
|---|
| 759 | | - if ((resplen + respoffs) > buflen) { |
|---|
| 760 | | - /* Device would have returned more data if buffer would |
|---|
| 761 | | - * have been big enough. Copy just the bits that we got. |
|---|
| 762 | | - */ |
|---|
| 763 | | - copylen = buflen - respoffs; |
|---|
| 764 | | - } else { |
|---|
| 765 | | - copylen = resplen; |
|---|
| 766 | | - } |
|---|
| 741 | + copylen = min(resplen, buflen - respoffs); |
|---|
| 767 | 742 | |
|---|
| 768 | 743 | if (copylen > *len) |
|---|
| 769 | 744 | copylen = *len; |
|---|
| .. | .. |
|---|
| 1707 | 1682 | int len, ret, max_pmkids; |
|---|
| 1708 | 1683 | |
|---|
| 1709 | 1684 | max_pmkids = priv->wdev.wiphy->max_num_pmkids; |
|---|
| 1710 | | - len = sizeof(*pmkids) + max_pmkids * sizeof(pmkids->bssid_info[0]); |
|---|
| 1685 | + len = struct_size(pmkids, bssid_info, max_pmkids); |
|---|
| 1711 | 1686 | |
|---|
| 1712 | 1687 | pmkids = kzalloc(len, GFP_KERNEL); |
|---|
| 1713 | 1688 | if (!pmkids) |
|---|
| .. | .. |
|---|
| 1740 | 1715 | int ret, len, num_pmkids; |
|---|
| 1741 | 1716 | |
|---|
| 1742 | 1717 | num_pmkids = le32_to_cpu(pmkids->bssid_info_count); |
|---|
| 1743 | | - len = sizeof(*pmkids) + num_pmkids * sizeof(pmkids->bssid_info[0]); |
|---|
| 1718 | + len = struct_size(pmkids, bssid_info, num_pmkids); |
|---|
| 1744 | 1719 | pmkids->length = cpu_to_le32(len); |
|---|
| 1745 | 1720 | |
|---|
| 1746 | 1721 | debug_print_pmkids(usbdev, pmkids, __func__); |
|---|
| .. | .. |
|---|
| 1761 | 1736 | struct cfg80211_pmksa *pmksa, |
|---|
| 1762 | 1737 | int max_pmkids) |
|---|
| 1763 | 1738 | { |
|---|
| 1764 | | - int i, newlen, err; |
|---|
| 1739 | + int i, err; |
|---|
| 1765 | 1740 | unsigned int count; |
|---|
| 1766 | 1741 | |
|---|
| 1767 | 1742 | count = le32_to_cpu(pmkids->bssid_info_count); |
|---|
| .. | .. |
|---|
| 1786 | 1761 | pmkids->bssid_info[i] = pmkids->bssid_info[i + 1]; |
|---|
| 1787 | 1762 | |
|---|
| 1788 | 1763 | count--; |
|---|
| 1789 | | - newlen = sizeof(*pmkids) + count * sizeof(pmkids->bssid_info[0]); |
|---|
| 1790 | | - |
|---|
| 1791 | | - pmkids->length = cpu_to_le32(newlen); |
|---|
| 1764 | + pmkids->length = cpu_to_le32(struct_size(pmkids, bssid_info, count)); |
|---|
| 1792 | 1765 | pmkids->bssid_info_count = cpu_to_le32(count); |
|---|
| 1793 | 1766 | |
|---|
| 1794 | 1767 | return pmkids; |
|---|
| .. | .. |
|---|
| 1831 | 1804 | } |
|---|
| 1832 | 1805 | |
|---|
| 1833 | 1806 | /* add new pmkid */ |
|---|
| 1834 | | - newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); |
|---|
| 1807 | + newlen = struct_size(pmkids, bssid_info, count + 1); |
|---|
| 1835 | 1808 | |
|---|
| 1836 | 1809 | new_pmkids = krealloc(pmkids, newlen, GFP_KERNEL); |
|---|
| 1837 | 1810 | if (!new_pmkids) { |
|---|
| .. | .. |
|---|
| 3123 | 3096 | __le32 num_items; |
|---|
| 3124 | 3097 | __le32 items[8]; |
|---|
| 3125 | 3098 | } networks_supported; |
|---|
| 3126 | | - struct ndis_80211_capability *caps; |
|---|
| 3127 | | - u8 caps_buf[sizeof(*caps) + sizeof(caps->auth_encr_pair) * 16]; |
|---|
| 3099 | + struct ndis_80211_capability caps; |
|---|
| 3128 | 3100 | int len, retval, i, n; |
|---|
| 3129 | 3101 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
|---|
| 3130 | 3102 | |
|---|
| .. | .. |
|---|
| 3133 | 3105 | retval = rndis_query_oid(usbdev, |
|---|
| 3134 | 3106 | RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED, |
|---|
| 3135 | 3107 | &networks_supported, &len); |
|---|
| 3136 | | - if (retval >= 0) { |
|---|
| 3108 | + if (!retval) { |
|---|
| 3137 | 3109 | n = le32_to_cpu(networks_supported.num_items); |
|---|
| 3138 | 3110 | if (n > 8) |
|---|
| 3139 | 3111 | n = 8; |
|---|
| .. | .. |
|---|
| 3154 | 3126 | } |
|---|
| 3155 | 3127 | |
|---|
| 3156 | 3128 | /* get device 802.11 capabilities, number of PMKIDs */ |
|---|
| 3157 | | - caps = (struct ndis_80211_capability *)caps_buf; |
|---|
| 3158 | | - len = sizeof(caps_buf); |
|---|
| 3129 | + len = sizeof(caps); |
|---|
| 3159 | 3130 | retval = rndis_query_oid(usbdev, |
|---|
| 3160 | 3131 | RNDIS_OID_802_11_CAPABILITY, |
|---|
| 3161 | | - caps, &len); |
|---|
| 3162 | | - if (retval >= 0) { |
|---|
| 3132 | + &caps, &len); |
|---|
| 3133 | + if (!retval) { |
|---|
| 3163 | 3134 | netdev_dbg(usbdev->net, "RNDIS_OID_802_11_CAPABILITY -> len %d, " |
|---|
| 3164 | 3135 | "ver %d, pmkids %d, auth-encr-pairs %d\n", |
|---|
| 3165 | | - le32_to_cpu(caps->length), |
|---|
| 3166 | | - le32_to_cpu(caps->version), |
|---|
| 3167 | | - le32_to_cpu(caps->num_pmkids), |
|---|
| 3168 | | - le32_to_cpu(caps->num_auth_encr_pair)); |
|---|
| 3169 | | - wiphy->max_num_pmkids = le32_to_cpu(caps->num_pmkids); |
|---|
| 3136 | + le32_to_cpu(caps.length), |
|---|
| 3137 | + le32_to_cpu(caps.version), |
|---|
| 3138 | + le32_to_cpu(caps.num_pmkids), |
|---|
| 3139 | + le32_to_cpu(caps.num_auth_encr_pair)); |
|---|
| 3140 | + wiphy->max_num_pmkids = le32_to_cpu(caps.num_pmkids); |
|---|
| 3170 | 3141 | } else |
|---|
| 3171 | 3142 | wiphy->max_num_pmkids = 0; |
|---|
| 3172 | 3143 | |
|---|