From 87c69d73bb4021bf3a26217b3a652ce262637b1e Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 12 Oct 2022 15:24:11 +0200 Subject: [PATCH 01/26] CI: bump actions/checkout action to v3 Bump actions/checkout action to v3 on every workflow to mute node deprecation warning. Signed-off-by: Christian Marangi --- .github/workflows/formal.yml | 2 +- .github/workflows/kernel.yml | 12 ++++++------ .github/workflows/tools.yml | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml index 8df31d1751..8083c5832c 100644 --- a/.github/workflows/formal.yml +++ b/.github/workflows/formal.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml index 25d6d265eb..f29b18d910 100644 --- a/.github/workflows/kernel.yml +++ b/.github/workflows/kernel.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set lower case owner name id: lower_owner @@ -83,30 +83,30 @@ jobs: steps: - name: Checkout master directory - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: openwrt - name: Checkout packages feed - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: openwrt/packages path: openwrt/feeds/packages - name: Checkout luci feed - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: openwrt/luci path: openwrt/feeds/luci - name: Checkout routing feed - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: openwrt/routing path: openwrt/feeds/routing - name: Checkout telephony feed - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: openwrt/telephony path: openwrt/feeds/telephony diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index f483615363..2661782f42 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: openwrt @@ -102,7 +102,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: 'openwrt' @@ -175,7 +175,7 @@ jobs: echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV" - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: 'openwrt' From 77b24012db1d696ca87c03fa1bb8bdf2606119e7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 12 Oct 2022 16:48:46 +0200 Subject: [PATCH 02/26] CI: bump actions/download,upload-artifact action to v3 Bump actions/download,upload-artifact action to v3 on every workflow to mute node deprecation warning. Signed-off-by: Christian Marangi --- .github/workflows/kernel.yml | 2 +- .github/workflows/tools.yml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml index f29b18d910..d8f98c531d 100644 --- a/.github/workflows/kernel.yml +++ b/.github/workflows/kernel.yml @@ -209,7 +209,7 @@ jobs: - name: Upload logs if: failure() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.TARGET }}-${{ env.SUBTARGET }}-logs path: "openwrt/logs" diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 2661782f42..def01678c6 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -84,14 +84,14 @@ jobs: - name: Upload logs if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macos-latest-logs path: ${{ env.WORKPATH }}/openwrt/logs - name: Upload config if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macos-latest-config path: ${{ env.WORKPATH }}/openwrt/.config @@ -132,14 +132,14 @@ jobs: - name: Upload logs if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: linux-buildbot-logs path: openwrt/logs - name: Upload config if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: linux-buildbot-config path: openwrt/.config @@ -152,7 +152,7 @@ jobs: - name: Upload prebuilt tools if: github.event_name == 'push' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: linux-buildbot-prebuilt-tools path: openwrt/tools.tar @@ -180,7 +180,7 @@ jobs: path: 'openwrt' - name: Download prebuilt tools from build job - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: linux-buildbot-prebuilt-tools path: openwrt From 5fb7232bc0592cb2e1818fa47dfaecc291c8514e Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 12 Oct 2022 16:49:46 +0200 Subject: [PATCH 03/26] CI: labeler: target major version of labeler action Target major version of labeler to include minor fixes and use always the latest major version with included fixes. Signed-off-by: Christian Marangi --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 420617809b..b67265ca80 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -14,6 +14,6 @@ jobs: name: Pull Request Labeler runs-on: ubuntu-latest steps: - - uses: actions/labeler@v4.0.1 + - uses: actions/labeler@v4 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' From 590eaaeed59a9eb6637a1480587fc410de182523 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Oct 2022 22:50:35 +0200 Subject: [PATCH 04/26] mac80211: fix issues in HE capabilities Enable HE SU beamformee by default Fix spatial reuse configuration: - he_spr_sr_control is not a bool for enabling, it contains multiple bits which disable features that should be disabled by default - one of the features (PSR) can be enabled through he_spr_psr_enabled - add option to disable bss color / spatial reuse Signed-off-by: Felix Fietkau --- .../files/lib/netifd/wireless/mac80211.sh | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index f462fc8ad9..66349f2599 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -51,6 +51,8 @@ drv_mac80211_init_device_config() { rx_antenna_pattern \ tx_antenna_pattern \ he_spr_sr_control \ + he_spr_psr_enabled \ + he_bss_color_enabled \ he_twt_required config_add_int \ beamformer_antennas \ @@ -414,12 +416,14 @@ mac80211_hostapd_setup_base() { if [ "$enable_ax" != "0" ]; then json_get_vars \ he_su_beamformer:1 \ - he_su_beamformee:0 \ + he_su_beamformee:1 \ he_mu_beamformer:1 \ he_twt_required:0 \ - he_spr_sr_control:0 \ - he_spr_non_srg_obss_pd_max_offset:1 \ - he_bss_color + he_spr_sr_control:3 \ + he_spr_psr_enabled:0 \ + he_spr_non_srg_obss_pd_max_offset:0 \ + he_bss_color:128 \ + he_bss_color_enabled:1 he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) he_phy_cap=${he_phy_cap:2} @@ -432,17 +436,25 @@ mac80211_hostapd_setup_base() { append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" } - set_default he_bss_color 128 - append base_cfg "he_bss_color=$he_bss_color" "$N" - - mac80211_add_he_capabilities \ + mac8q0211_add_he_capabilities \ he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ - he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \ + he_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required - [ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + if [ "$he_bss_color_enabled" -gt 0 ]; then + append base_cfg "he_bss_color=$he_bss_color" "$N" + [ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ + append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) + } + [ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) + append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" + else + append base_cfg "he_bss_color_disabled=1" "$N" + fi + append base_cfg "he_default_pe_duration=4" "$N" append base_cfg "he_rts_threshold=1023" "$N" From 26f400210d6b3780fcc0deb89b9741837df9c8b8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 13 Oct 2022 14:29:53 +0200 Subject: [PATCH 05/26] mac80211: backport security fixes This mainly affects scanning and beacon parsing, especially with MBSSID enabled Fixes: CVE-2022-41674 Fixes: CVE-2022-42719 Fixes: CVE-2022-42720 Fixes: CVE-2022-42721 Fixes: CVE-2022-42722 Signed-off-by: Felix Fietkau --- ...80211-mesh-clean-up-rx_bcn_presp-API.patch | 110 ++ ...ove-CRC-into-struct-ieee802_11_elems.patch | 82 ++ ...11-mlme-find-auth-challenge-directly.patch | 80 ++ ...ays-allocate-struct-ieee802_11_elems.patch | 1143 +++++++++++++++++ ...ix-memory-leaks-with-element-parsing.patch | 115 ++ ...x-u8-overflow-in-cfg80211_update_not.patch | 41 + ...-mac80211-reject-bad-MBSSID-elements.patch | 47 + ...11-fix-MBSSID-parsing-use-after-free.patch | 94 ++ ...sure-length-byte-is-present-before-a.patch | 41 + ...fi-cfg80211-fix-BSS-refcounting-bugs.patch | 87 ++ ...oid-nontransmitted-BSS-list-corrupti.patch | 48 + ...sim-avoid-mac80211-warning-on-bad-ra.patch | 31 + ...x-crash-in-beacon-protection-for-P2P.patch | 52 + ...update-hidden-BSSes-to-avoid-WARN_ON.patch | 85 ++ ...ac80211-Fix-UAF-in-ieee80211_scan_rx.patch | 2 +- ...on.patch => 363-bss-color-collision.patch} | 4 +- 16 files changed, 2059 insertions(+), 3 deletions(-) create mode 100644 package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch create mode 100644 package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch create mode 100644 package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch create mode 100644 package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch create mode 100644 package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch create mode 100644 package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch create mode 100644 package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch create mode 100644 package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch create mode 100644 package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch create mode 100644 package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch create mode 100644 package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch create mode 100644 package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch create mode 100644 package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch create mode 100644 package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch rename package/kernel/mac80211/patches/subsys/{350-bss-color-collision.patch => 363-bss-color-collision.patch} (96%) diff --git a/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch b/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch new file mode 100644 index 0000000000..3fa70b05fd --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch @@ -0,0 +1,110 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:07 +0200 +Subject: [PATCH] mac80211: mesh: clean up rx_bcn_presp API + +commit a5b983c6073140b624f64e79fea6d33c3e4315a0 upstream. + +We currently pass the entire elements to the rx_bcn_presp() +method, but only need mesh_config. Additionally, we use the +length of the elements to calculate back the entire frame's +length, but that's confusing - just pass the length of the +frame instead. + +Link: https://lore.kernel.org/r/20210920154009.a18ed3d2da6c.I1824b773a0fbae4453e1433c184678ca14e8df45@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -645,10 +645,9 @@ struct ieee80211_if_ocb { + */ + struct ieee802_11_elems; + struct ieee80211_mesh_sync_ops { +- void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, +- u16 stype, +- struct ieee80211_mgmt *mgmt, +- struct ieee802_11_elems *elems, ++ void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, u16 stype, ++ struct ieee80211_mgmt *mgmt, unsigned int len, ++ const struct ieee80211_meshconf_ie *mesh_cfg, + struct ieee80211_rx_status *rx_status); + + /* should be called with beacon_data under RCU read lock */ +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1354,8 +1354,8 @@ static void ieee80211_mesh_rx_bcn_presp( + } + + if (ifmsh->sync_ops) +- ifmsh->sync_ops->rx_bcn_presp(sdata, +- stype, mgmt, &elems, rx_status); ++ ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len, ++ elems.mesh_config, rx_status); + } + + int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) +--- a/net/mac80211/mesh_sync.c ++++ b/net/mac80211/mesh_sync.c +@@ -3,6 +3,7 @@ + * Copyright 2011-2012, Pavel Zubarev + * Copyright 2011-2012, Marco Porsch + * Copyright 2011-2012, cozybit Inc. ++ * Copyright (C) 2021 Intel Corporation + */ + + #include "ieee80211_i.h" +@@ -35,12 +36,12 @@ struct sync_method { + /** + * mesh_peer_tbtt_adjusting - check if an mp is currently adjusting its TBTT + * +- * @ie: information elements of a management frame from the mesh peer ++ * @cfg: mesh config element from the mesh peer (or %NULL) + */ +-static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) ++static bool mesh_peer_tbtt_adjusting(const struct ieee80211_meshconf_ie *cfg) + { +- return (ie->mesh_config->meshconf_cap & +- IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; ++ return cfg && ++ (cfg->meshconf_cap & IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING); + } + + void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata) +@@ -76,11 +77,11 @@ void mesh_sync_adjust_tsf(struct ieee802 + } + } + +-static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, +- u16 stype, +- struct ieee80211_mgmt *mgmt, +- struct ieee802_11_elems *elems, +- struct ieee80211_rx_status *rx_status) ++static void ++mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, u16 stype, ++ struct ieee80211_mgmt *mgmt, unsigned int len, ++ const struct ieee80211_meshconf_ie *mesh_cfg, ++ struct ieee80211_rx_status *rx_status) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + struct ieee80211_local *local = sdata->local; +@@ -101,10 +102,7 @@ static void mesh_sync_offset_rx_bcn_pres + */ + if (ieee80211_have_rx_timestamp(rx_status)) + t_r = ieee80211_calculate_rx_timestamp(local, rx_status, +- 24 + 12 + +- elems->total_len + +- FCS_LEN, +- 24); ++ len + FCS_LEN, 24); + else + t_r = drv_get_tsf(local, sdata); + +@@ -119,7 +117,7 @@ static void mesh_sync_offset_rx_bcn_pres + * dot11MeshNbrOffsetMaxNeighbor non-peer non-MBSS neighbors + */ + +- if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { ++ if (mesh_peer_tbtt_adjusting(mesh_cfg)) { + msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", + sta->sta.addr); + goto no_sync; diff --git a/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch b/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch new file mode 100644 index 0000000000..e44aac5cba --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch @@ -0,0 +1,82 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:08 +0200 +Subject: [PATCH] mac80211: move CRC into struct ieee802_11_elems + +commit c6e37ed498f958254b5459253199e816b6bfc52f upstream. + +We're currently returning this value, but to prepare for +returning the allocated structure, move it into there. + +Link: https://lore.kernel.org/r/20210920154009.479b8ebf999d.If0d4ba75ee38998dc3eeae25058aa748efcb2fc9@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1530,6 +1530,7 @@ struct ieee80211_csa_ie { + struct ieee802_11_elems { + const u8 *ie_start; + size_t total_len; ++ u32 crc; + + /* pointers to IEs */ + const struct ieee80211_tdls_lnkie *lnk_id; +@@ -2089,10 +2090,10 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid); ++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ++ struct ieee802_11_elems *elems, ++ u64 filter, u32 crc, u8 *transmitter_bssid, ++ u8 *bss_bssid); + static inline void ieee802_11_parse_elems(const u8 *start, size_t len, + bool action, + struct ieee802_11_elems *elems, +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4102,10 +4102,11 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ncrc = ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); ++ ieee802_11_parse_elems_crc(variable, ++ len - baselen, false, &elems, ++ care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ ncrc = elems.crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && + ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1469,10 +1469,10 @@ static size_t ieee802_11_find_bssid_prof + return found ? profile_len : 0; + } + +-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid) ++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ++ struct ieee802_11_elems *elems, ++ u64 filter, u32 crc, u8 *transmitter_bssid, ++ u8 *bss_bssid) + { + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; +@@ -1524,7 +1524,7 @@ u32 ieee802_11_parse_elems_crc(const u8 + + kfree(nontransmitted_profile); + +- return crc; ++ elems->crc = crc; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch b/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch new file mode 100644 index 0000000000..3432c25a91 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch @@ -0,0 +1,80 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:09 +0200 +Subject: [PATCH] mac80211: mlme: find auth challenge directly + +commit 49a765d6785e99157ff5091cc37485732496864e upstream. + +There's no need to parse all elements etc. just to find the +authentication challenge - use cfg80211_find_elem() instead. +This also allows us to remove WLAN_EID_CHALLENGE handling +from the element parsing entirely. + +Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1540,7 +1540,6 @@ struct ieee802_11_elems { + const u8 *supp_rates; + const u8 *ds_params; + const struct ieee80211_tim_ie *tim; +- const u8 *challenge; + const u8 *rsn; + const u8 *rsnx; + const u8 *erp_info; +@@ -1594,7 +1593,6 @@ struct ieee802_11_elems { + u8 ssid_len; + u8 supp_rates_len; + u8 tim_len; +- u8 challenge_len; + u8 rsn_len; + u8 rsnx_len; + u8 ext_supp_rates_len; +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2889,17 +2889,17 @@ static void ieee80211_auth_challenge(str + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; ++ const struct element *challenge; + u8 *pos; +- struct ieee802_11_elems elems; + u32 tx_flags = 0; + struct ieee80211_prep_tx_info info = { + .subtype = IEEE80211_STYPE_AUTH, + }; + + pos = mgmt->u.auth.variable; +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, auth_data->bss->bssid); +- if (!elems.challenge) ++ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos, ++ len - (pos - (u8 *)mgmt)); ++ if (!challenge) + return; + auth_data->expected_transaction = 4; + drv_mgd_prepare_tx(sdata->local, sdata, &info); +@@ -2907,7 +2907,8 @@ static void ieee80211_auth_challenge(str + tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_INTFL_MLME_CONN_TX; + ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, +- elems.challenge - 2, elems.challenge_len + 2, ++ (void *)challenge, ++ challenge->datalen + sizeof(*challenge), + auth_data->bss->bssid, auth_data->bss->bssid, + auth_data->key, auth_data->key_len, + auth_data->key_idx, tx_flags); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1120,10 +1120,6 @@ _ieee802_11_parse_elems_crc(const u8 *st + } else + elem_parse_failed = true; + break; +- case WLAN_EID_CHALLENGE: +- elems->challenge = pos; +- elems->challenge_len = elen; +- break; + case WLAN_EID_VENDOR_SPECIFIC: + if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && + pos[2] == 0xf2) { diff --git a/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch b/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch new file mode 100644 index 0000000000..75655279a9 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch @@ -0,0 +1,1143 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:10 +0200 +Subject: [PATCH] mac80211: always allocate struct ieee802_11_elems + +As the 802.11 spec evolves, we need to parse more and more +elements. This is causing the struct to grow, and we can no +longer get away with putting it on the stack. + +Change the API to always dynamically allocate and return an +allocated pointer that must be kfree()d later. + +As an alternative, I contemplated a scheme whereby we'd say +in the code which elements we needed, e.g. + + DECLARE_ELEMENT_PARSER(elems, + SUPPORTED_CHANNELS, + CHANNEL_SWITCH, + EXT(KEY_DELIVERY)); + + ieee802_11_parse_elems(..., &elems, ...); + +and while I think this is possible and will save us a lot +since most individual places only care about a small subset +of the elements, it ended up being a bit more work since a +lot of places do the parsing and then pass the struct to +other functions, sometimes with multiple levels. + +Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -478,7 +478,7 @@ void ieee80211_process_addba_request(str + size_t len) + { + u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; +- struct ieee802_11_elems elems = { }; ++ struct ieee802_11_elems *elems = NULL; + u8 dialog_token; + int ies_len; + +@@ -496,16 +496,17 @@ void ieee80211_process_addba_request(str + ies_len = len - offsetof(struct ieee80211_mgmt, + u.action.u.addba_req.variable); + if (ies_len) { +- ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); +- if (elems.parse_error) ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, ++ ies_len, true, mgmt->bssid, NULL); ++ if (!elems || elems->parse_error) + return; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, +- elems.addba_ext_ie); ++ elems ? elems->addba_ext_ie : NULL); ++ kfree(elems); + } + + void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -9,7 +9,7 @@ + * Copyright 2009, Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH +- * Copyright(c) 2018-2020 Intel Corporation ++ * Copyright(c) 2018-2021 Intel Corporation + */ + + #include +@@ -1589,7 +1589,7 @@ void ieee80211_rx_mgmt_probe_beacon(stru + struct ieee80211_rx_status *rx_status) + { + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + + BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) != + offsetof(typeof(mgmt->u.beacon), variable)); +@@ -1602,10 +1602,14 @@ void ieee80211_rx_mgmt_probe_beacon(stru + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); +- +- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, false, ++ mgmt->bssid, NULL); ++ ++ if (elems) { ++ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems); ++ kfree(elems); ++ } + } + + void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, +@@ -1614,7 +1618,7 @@ void ieee80211_ibss_rx_queued_mgmt(struc + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ies_len; + + rx_status = IEEE80211_SKB_RXCB(skb); +@@ -1651,15 +1655,16 @@ void ieee80211_ibss_rx_queued_mgmt(struc + if (ies_len < 0) + break; + +- ieee802_11_parse_elems( ++ elems = ieee802_11_parse_elems( + mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, &elems); ++ rx_status, elems); ++ kfree(elems); + break; + } + } +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2088,18 +2088,18 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid); +-static inline void ieee802_11_parse_elems(const u8 *start, size_t len, +- bool action, +- struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, ++ u64 filter, u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid); ++static inline struct ieee802_11_elems * ++ieee802_11_parse_elems(const u8 *start, size_t len, bool action, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { +- ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0, +- transmitter_bssid, bss_bssid); ++ return ieee802_11_parse_elems_crc(start, len, action, 0, 0, ++ transmitter_bssid, bss_bssid); + } + + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1247,7 +1247,7 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + struct sk_buff *presp; + struct beacon_data *bcn; + struct ieee80211_mgmt *hdr; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *pos; + +@@ -1256,22 +1256,24 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + if (baselen > len) + return; + +- ieee802_11_parse_elems(pos, len - baselen, false, &elems, mgmt->bssid, +- NULL); +- +- if (!elems.mesh_id) ++ elems = ieee802_11_parse_elems(pos, len - baselen, false, mgmt->bssid, ++ NULL); ++ if (!elems) + return; + ++ if (!elems->mesh_id) ++ goto free; ++ + /* 802.11-2012 10.1.4.3.2 */ + if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && + !is_broadcast_ether_addr(mgmt->da)) || +- elems.ssid_len != 0) +- return; ++ elems->ssid_len != 0) ++ goto free; + +- if (elems.mesh_id_len != 0 && +- (elems.mesh_id_len != ifmsh->mesh_id_len || +- memcmp(elems.mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) +- return; ++ if (elems->mesh_id_len != 0 && ++ (elems->mesh_id_len != ifmsh->mesh_id_len || ++ memcmp(elems->mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) ++ goto free; + + rcu_read_lock(); + bcn = rcu_dereference(ifmsh->beacon); +@@ -1295,6 +1297,8 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + ieee80211_tx_skb(sdata, presp); + out: + rcu_read_unlock(); ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, +@@ -1305,7 +1309,7 @@ static void ieee80211_mesh_rx_bcn_presp( + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_channel *channel; + size_t baselen; + int freq; +@@ -1320,42 +1324,47 @@ static void ieee80211_mesh_rx_bcn_presp( + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, ++ false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + + /* ignore non-mesh or secure / unsecure mismatch */ +- if ((!elems.mesh_id || !elems.mesh_config) || +- (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || +- (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) +- return; ++ if ((!elems->mesh_id || !elems->mesh_config) || ++ (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || ++ (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) ++ goto free; + +- if (elems.ds_params) +- freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); ++ if (elems->ds_params) ++ freq = ieee80211_channel_to_frequency(elems->ds_params[0], band); + else + freq = rx_status->freq; + + channel = ieee80211_get_channel(local->hw.wiphy, freq); + + if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) +- return; ++ goto free; + +- if (mesh_matches_local(sdata, &elems)) { ++ if (mesh_matches_local(sdata, elems)) { + mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n", + sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal); + if (!sdata->u.mesh.user_mpm || + sdata->u.mesh.mshcfg.rssi_threshold == 0 || + sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) +- mesh_neighbour_update(sdata, mgmt->sa, &elems, ++ mesh_neighbour_update(sdata, mgmt->sa, elems, + rx_status); + + if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT && + !sdata->vif.csa_active) +- ieee80211_mesh_process_chnswitch(sdata, &elems, true); ++ ieee80211_mesh_process_chnswitch(sdata, elems, true); + } + + if (ifmsh->sync_ops) + ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len, +- elems.mesh_config, rx_status); ++ elems->mesh_config, rx_status); ++free: ++ kfree(elems); + } + + int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) +@@ -1447,7 +1456,7 @@ static void mesh_rx_csa_frame(struct iee + struct ieee80211_mgmt *mgmt, size_t len) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + u16 pre_value; + bool fwd_csa = true; + size_t baselen; +@@ -1460,33 +1469,37 @@ static void mesh_rx_csa_frame(struct iee + pos = mgmt->u.action.u.chan_switch.variable; + baselen = offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +- ieee802_11_parse_elems(pos, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- +- if (!mesh_matches_local(sdata, &elems)) ++ elems = ieee802_11_parse_elems(pos, len - baselen, true, ++ mgmt->bssid, NULL); ++ if (!elems) + return; + +- ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; ++ if (!mesh_matches_local(sdata, elems)) ++ goto free; ++ ++ ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl; + if (!--ifmsh->chsw_ttl) + fwd_csa = false; + +- pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); ++ pre_value = le16_to_cpu(elems->mesh_chansw_params_ie->mesh_pre_value); + if (ifmsh->pre_value >= pre_value) +- return; ++ goto free; + + ifmsh->pre_value = pre_value; + + if (!sdata->vif.csa_active && +- !ieee80211_mesh_process_chnswitch(sdata, &elems, false)) { ++ !ieee80211_mesh_process_chnswitch(sdata, elems, false)) { + mcsa_dbg(sdata, "Failed to process CSA action frame"); +- return; ++ goto free; + } + + /* forward or re-broadcast the CSA frame */ + if (fwd_csa) { +- if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0) ++ if (mesh_fwd_csa_frame(sdata, mgmt, len, elems) < 0) + mcsa_dbg(sdata, "Failed to forward the CSA frame"); + } ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + +@@ -908,7 +908,7 @@ static void hwmp_rann_frame_process(stru + void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mgmt *mgmt, size_t len) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u32 path_metric; + struct sta_info *sta; +@@ -926,37 +926,41 @@ void mesh_rx_path_sel_frame(struct ieee8 + rcu_read_unlock(); + + baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; +- ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, +- len - baselen, false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, ++ len - baselen, false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + +- if (elems.preq) { +- if (elems.preq_len != 37) ++ if (elems->preq) { ++ if (elems->preq_len != 37) + /* Right now we support just 1 destination and no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.preq, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->preq, + MPATH_PREQ); + if (path_metric) +- hwmp_preq_frame_process(sdata, mgmt, elems.preq, ++ hwmp_preq_frame_process(sdata, mgmt, elems->preq, + path_metric); + } +- if (elems.prep) { +- if (elems.prep_len != 31) ++ if (elems->prep) { ++ if (elems->prep_len != 31) + /* Right now we support no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.prep, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep, + MPATH_PREP); + if (path_metric) +- hwmp_prep_frame_process(sdata, mgmt, elems.prep, ++ hwmp_prep_frame_process(sdata, mgmt, elems->prep, + path_metric); + } +- if (elems.perr) { +- if (elems.perr_len != 15) ++ if (elems->perr) { ++ if (elems->perr_len != 15) + /* Right now we support only one destination per PERR */ +- return; +- hwmp_perr_frame_process(sdata, mgmt, elems.perr); ++ goto free; ++ hwmp_perr_frame_process(sdata, mgmt, elems->perr); + } +- if (elems.rann) +- hwmp_rann_frame_process(sdata, mgmt, elems.rann); ++ if (elems->rann) ++ hwmp_rann_frame_process(sdata, mgmt, elems->rann); ++free: ++ kfree(elems); + } + + /** +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + #include +@@ -1200,7 +1200,7 @@ void mesh_rx_plink_frame(struct ieee8021 + struct ieee80211_mgmt *mgmt, size_t len, + struct ieee80211_rx_status *rx_status) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *baseaddr; + +@@ -1228,7 +1228,8 @@ void mesh_rx_plink_frame(struct ieee8021 + if (baselen > len) + return; + } +- ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- mesh_process_plink_frame(sdata, mgmt, &elems, rx_status); ++ elems = ieee802_11_parse_elems(baseaddr, len - baselen, true, ++ mgmt->bssid, NULL); ++ mesh_process_plink_frame(sdata, mgmt, elems, rx_status); ++ kfree(elems); + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3317,8 +3317,11 @@ static bool ieee80211_assoc_success(stru + aid = 0; /* TODO */ + } + capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ ++ if (!elems) ++ return false; + + if (elems->aid_resp) + aid = le16_to_cpu(elems->aid_resp->aid); +@@ -3340,7 +3343,8 @@ static bool ieee80211_assoc_success(stru + + if (!is_s1g && !elems->supp_rates) { + sdata_info(sdata, "no SuppRates element in AssocResp\n"); +- return false; ++ ret = false; ++ goto out; + } + + sdata->vif.bss_conf.aid = aid; +@@ -3362,7 +3366,7 @@ static bool ieee80211_assoc_success(stru + (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && + (!elems->vht_cap_elem || !elems->vht_operation)))) { + const struct cfg80211_bss_ies *ies; +- struct ieee802_11_elems bss_elems; ++ struct ieee802_11_elems *bss_elems; + + rcu_read_lock(); + ies = rcu_dereference(cbss->ies); +@@ -3373,13 +3377,17 @@ static bool ieee80211_assoc_success(stru + if (!bss_ies) + return false; + +- ieee802_11_parse_elems(bss_ies->data, bss_ies->len, +- false, &bss_elems, +- mgmt->bssid, +- assoc_data->bss->bssid); ++ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, ++ false, mgmt->bssid, ++ assoc_data->bss->bssid); ++ if (!bss_elems) { ++ ret = false; ++ goto out; ++ } ++ + if (assoc_data->wmm && +- !elems->wmm_param && bss_elems.wmm_param) { +- elems->wmm_param = bss_elems.wmm_param; ++ !elems->wmm_param && bss_elems->wmm_param) { ++ elems->wmm_param = bss_elems->wmm_param; + sdata_info(sdata, + "AP bug: WMM param missing from AssocResp\n"); + } +@@ -3388,30 +3396,32 @@ static bool ieee80211_assoc_success(stru + * Also check if we requested HT/VHT, otherwise the AP doesn't + * have to include the IEs in the (re)association response. + */ +- if (!elems->ht_cap_elem && bss_elems.ht_cap_elem && ++ if (!elems->ht_cap_elem && bss_elems->ht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_cap_elem = bss_elems.ht_cap_elem; ++ elems->ht_cap_elem = bss_elems->ht_cap_elem; + sdata_info(sdata, + "AP bug: HT capability missing from AssocResp\n"); + } +- if (!elems->ht_operation && bss_elems.ht_operation && ++ if (!elems->ht_operation && bss_elems->ht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_operation = bss_elems.ht_operation; ++ elems->ht_operation = bss_elems->ht_operation; + sdata_info(sdata, + "AP bug: HT operation missing from AssocResp\n"); + } +- if (!elems->vht_cap_elem && bss_elems.vht_cap_elem && ++ if (!elems->vht_cap_elem && bss_elems->vht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_cap_elem = bss_elems.vht_cap_elem; ++ elems->vht_cap_elem = bss_elems->vht_cap_elem; + sdata_info(sdata, + "AP bug: VHT capa missing from AssocResp\n"); + } +- if (!elems->vht_operation && bss_elems.vht_operation && ++ if (!elems->vht_operation && bss_elems->vht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_operation = bss_elems.vht_operation; ++ elems->vht_operation = bss_elems->vht_operation; + sdata_info(sdata, + "AP bug: VHT operation missing from AssocResp\n"); + } ++ ++ kfree(bss_elems); + } + + /* +@@ -3662,6 +3672,7 @@ static bool ieee80211_assoc_success(stru + + ret = true; + out: ++ kfree(elems); + kfree(bss_ies); + return ret; + } +@@ -3673,7 +3684,7 @@ static void ieee80211_rx_mgmt_assoc_resp + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; + u16 capab_info, status_code, aid; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ac, uapsd_queues = -1; + u8 *pos; + bool reassoc; +@@ -3730,14 +3741,16 @@ static void ieee80211_rx_mgmt_assoc_resp + fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0) + return; + +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ if (!elems) ++ goto notify_driver; + + if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && +- elems.timeout_int && +- elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { ++ elems->timeout_int && ++ elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { + u32 tu, ms; +- tu = le32_to_cpu(elems.timeout_int->value); ++ tu = le32_to_cpu(elems->timeout_int->value); + ms = tu * 1024 / 1000; + sdata_info(sdata, + "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", +@@ -3757,7 +3770,7 @@ static void ieee80211_rx_mgmt_assoc_resp + event.u.mlme.reason = status_code; + drv_event_callback(sdata->local, sdata, &event); + } else { +- if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) { ++ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) { + /* oops -- internal error -- send timeout for now */ + ieee80211_destroy_assoc_data(sdata, false, false); + cfg80211_assoc_timeout(sdata->dev, cbss); +@@ -3787,6 +3800,7 @@ static void ieee80211_rx_mgmt_assoc_resp + ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len); + notify_driver: + drv_mgd_complete_tx(sdata->local, sdata, &info); ++ kfree(elems); + } + + static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, +@@ -3991,7 +4005,7 @@ static void ieee80211_rx_mgmt_beacon(str + struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; + struct ieee80211_mgmt *mgmt = (void *) hdr; + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_channel *chan; +@@ -4037,15 +4051,16 @@ static void ieee80211_rx_mgmt_beacon(str + + if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && + ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) { +- ieee802_11_parse_elems(variable, +- len - baselen, false, &elems, +- bssid, +- ifmgd->assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(variable, len - baselen, false, ++ bssid, ++ ifmgd->assoc_data->bss->bssid); ++ if (!elems) ++ return; + + ieee80211_rx_bss_info(sdata, mgmt, len, rx_status); + +- if (elems.dtim_period) +- ifmgd->dtim_period = elems.dtim_period; ++ if (elems->dtim_period) ++ ifmgd->dtim_period = elems->dtim_period; + ifmgd->have_beacon = true; + ifmgd->assoc_data->need_beacon = false; + if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) { +@@ -4053,17 +4068,17 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + +- if (elems.mbssid_config_ie) ++ if (elems->mbssid_config_ie) + bss_conf->profile_periodicity = +- elems.mbssid_config_ie->profile_periodicity; ++ elems->mbssid_config_ie->profile_periodicity; + else + bss_conf->profile_periodicity = 0; + +- if (elems.ext_capab_len >= 11 && +- (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) ++ if (elems->ext_capab_len >= 11 && ++ (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) + bss_conf->ema_ap = true; + else + bss_conf->ema_ap = false; +@@ -4072,6 +4087,7 @@ static void ieee80211_rx_mgmt_beacon(str + ifmgd->assoc_data->timeout = jiffies; + ifmgd->assoc_data->timeout_started = true; + run_again(sdata, ifmgd->assoc_data->timeout); ++ kfree(elems); + return; + } + +@@ -4103,14 +4119,15 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); +- ncrc = elems.crc; ++ elems = ieee802_11_parse_elems_crc(variable, len - baselen, ++ false, care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ if (!elems) ++ return; ++ ncrc = elems->crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && +- ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { ++ ieee80211_check_tim(elems->tim, elems->tim_len, bss_conf->aid)) { + if (local->hw.conf.dynamic_ps_timeout > 0) { + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; +@@ -4180,12 +4197,12 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + + if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) || + ieee80211_is_s1g_short_beacon(mgmt->frame_control)) +- return; ++ goto free; + ifmgd->beacon_crc = ncrc; + ifmgd->beacon_crc_valid = true; + +@@ -4193,12 +4210,12 @@ static void ieee80211_rx_mgmt_beacon(str + + ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + rx_status->device_timestamp, +- &elems, true); ++ elems, true); + + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && +- ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, +- elems.wmm_param_len, +- elems.mu_edca_param_set)) ++ ieee80211_sta_wmm_params(local, sdata, elems->wmm_param, ++ elems->wmm_param_len, ++ elems->mu_edca_param_set)) + changed |= BSS_CHANGED_QOS; + + /* +@@ -4207,7 +4224,7 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ifmgd->have_beacon) { + /* a few bogus AP send dtim_period = 0 or no TIM IE */ +- bss_conf->dtim_period = elems.dtim_period ?: 1; ++ bss_conf->dtim_period = elems->dtim_period ?: 1; + + changed |= BSS_CHANGED_BEACON_INFO; + ifmgd->have_beacon = true; +@@ -4219,9 +4236,9 @@ static void ieee80211_rx_mgmt_beacon(str + ieee80211_recalc_ps_vif(sdata); + } + +- if (elems.erp_info) { ++ if (elems->erp_info) { + erp_valid = true; +- erp_value = elems.erp_info[0]; ++ erp_value = elems->erp_info[0]; + } else { + erp_valid = false; + } +@@ -4234,12 +4251,12 @@ static void ieee80211_rx_mgmt_beacon(str + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, bssid); + +- changed |= ieee80211_recalc_twt_req(sdata, sta, &elems); ++ changed |= ieee80211_recalc_twt_req(sdata, sta, elems); + +- if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem, +- elems.vht_cap_elem, elems.ht_operation, +- elems.vht_operation, elems.he_operation, +- elems.s1g_oper, bssid, &changed)) { ++ if (ieee80211_config_bw(sdata, sta, elems->ht_cap_elem, ++ elems->vht_cap_elem, elems->ht_operation, ++ elems->vht_operation, elems->he_operation, ++ elems->s1g_oper, bssid, &changed)) { + mutex_unlock(&local->sta_mtx); + sdata_info(sdata, + "failed to follow AP %pM bandwidth change, disconnect\n", +@@ -4251,21 +4268,23 @@ static void ieee80211_rx_mgmt_beacon(str + sizeof(deauth_buf), true, + WLAN_REASON_DEAUTH_LEAVING, + false); +- return; ++ goto free; + } + +- if (sta && elems.opmode_notif) +- ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, ++ if (sta && elems->opmode_notif) ++ ieee80211_vht_handle_opmode(sdata, sta, *elems->opmode_notif, + rx_status->band); + mutex_unlock(&local->sta_mtx); + + changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, +- elems.country_elem, +- elems.country_elem_len, +- elems.pwr_constr_elem, +- elems.cisco_dtpc_elem); ++ elems->country_elem, ++ elems->country_elem_len, ++ elems->pwr_constr_elem, ++ elems->cisco_dtpc_elem); + + ieee80211_bss_info_change_notify(sdata, changed); ++free: ++ kfree(elems); + } + + void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, +@@ -4294,7 +4313,6 @@ void ieee80211_sta_rx_queued_mgmt(struct + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; + int ies_len; + + rx_status = (struct ieee80211_rx_status *) skb->cb; +@@ -4326,6 +4344,8 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + case IEEE80211_STYPE_ACTION: + if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +@@ -4334,18 +4354,21 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + + /* CSA IE cannot be overridden, no need for BSSID */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.ext_chan_switch.variable); +@@ -4357,21 +4380,22 @@ void ieee80211_sta_rx_queued_mgmt(struct + * extended CSA IE can't be overridden, no need for + * BSSID + */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.ext_chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.ext_chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + /* for the handling code pretend this was also an IE */ +- elems.ext_chansw_ie = ++ elems->ext_chansw_ie = + &mgmt->u.action.u.ext_chan_switch.data; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } + break; + } +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -9,7 +9,7 @@ + * Copyright 2007, Michael Wu + * Copyright 2013-2015 Intel Mobile Communications GmbH + * Copyright 2016-2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #include +@@ -155,7 +155,7 @@ ieee80211_bss_info_update(struct ieee802 + }; + bool signal_valid; + struct ieee80211_sub_if_data *scan_sdata; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *elements; + +@@ -209,8 +209,10 @@ ieee80211_bss_info_update(struct ieee802 + if (baselen > len) + return NULL; + +- ieee802_11_parse_elems(elements, len - baselen, false, &elems, +- mgmt->bssid, cbss->bssid); ++ elems = ieee802_11_parse_elems(elements, len - baselen, false, ++ mgmt->bssid, cbss->bssid); ++ if (!elems) ++ return NULL; + + /* In case the signal is invalid update the status */ + signal_valid = channel == cbss->channel; +@@ -218,15 +220,17 @@ ieee80211_bss_info_update(struct ieee802 + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + + bss = (void *)cbss->priv; +- ieee80211_update_bss_from_elems(local, bss, &elems, rx_status, beacon); ++ ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon); + + list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) { + non_tx_bss = (void *)non_tx_cbss->priv; + +- ieee80211_update_bss_from_elems(local, non_tx_bss, &elems, ++ ieee80211_update_bss_from_elems(local, non_tx_bss, elems, + rx_status, beacon); + } + ++ kfree(elems); ++ + return bss; + } + +--- a/net/mac80211/tdls.c ++++ b/net/mac80211/tdls.c +@@ -6,7 +6,7 @@ + * Copyright 2014, Intel Corporation + * Copyright 2014 Intel Mobile Communications GmbH + * Copyright 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + */ + + #include +@@ -1684,7 +1684,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems = NULL; + struct sta_info *sta; + struct ieee80211_tdls_data *tf = (void *)skb->data; + bool local_initiator; +@@ -1718,16 +1718,20 @@ ieee80211_process_tdls_channel_switch_re + goto call_drv; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, +- skb->len - baselen, false, &elems, +- NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n"); + ret = -EINVAL; + goto out; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); + ret = -EINVAL; + goto out; +@@ -1735,15 +1739,15 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; + goto out; + } + +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, ¶ms.ch_sw_tm_ie); +@@ -1763,6 +1767,7 @@ call_drv: + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++ kfree(elems); + return ret; + } + +@@ -1771,7 +1776,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct cfg80211_chan_def chandef; + struct ieee80211_channel *chan; + enum nl80211_channel_type chan_type; +@@ -1831,22 +1836,27 @@ ieee80211_process_tdls_channel_switch_re + return -EINVAL; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_req.variable, +- skb->len - baselen, false, &elems, NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) ++ return -ENOMEM; ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.sec_chan_offs) { ++ if (!elems->sec_chan_offs) { + chan_type = NL80211_CHAN_HT20; + } else { +- switch (elems.sec_chan_offs->sec_chan_offs) { ++ switch (elems->sec_chan_offs->sec_chan_offs) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + chan_type = NL80211_CHAN_HT40PLUS; + break; +@@ -1865,7 +1875,8 @@ ieee80211_process_tdls_channel_switch_re + if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef, + sdata->wdev.iftype)) { + tdls_dbg(sdata, "TDLS chan switch to forbidden channel\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + + mutex_lock(&local->sta_mtx); +@@ -1881,7 +1892,7 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; +@@ -1889,16 +1900,16 @@ ieee80211_process_tdls_channel_switch_re + } + + /* peer should have known better */ +- if (!sta->sta.ht_cap.ht_supported && elems.sec_chan_offs && +- elems.sec_chan_offs->sec_chan_offs) { ++ if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs && ++ elems->sec_chan_offs->sec_chan_offs) { + tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); + ret = -ENOTSUPP; + goto out; + } + + params.chandef = &chandef; +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, +@@ -1917,6 +1928,8 @@ ieee80211_process_tdls_channel_switch_re + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++free: ++ kfree(elems); + return ret; + } + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1399,8 +1399,8 @@ _ieee802_11_parse_elems_crc(const u8 *st + + static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid, + u8 *nontransmitted_profile) + { + const struct element *elem, *sub; +@@ -1465,16 +1465,20 @@ static size_t ieee802_11_find_bssid_prof + return found ? profile_len : 0; + } + +-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, +- struct ieee802_11_elems *elems, +- u64 filter, u32 crc, u8 *transmitter_bssid, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, u64 filter, ++ u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { ++ struct ieee802_11_elems *elems; + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; + +- memset(elems, 0, sizeof(*elems)); ++ elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ if (!elems) ++ return NULL; + elems->ie_start = start; + elems->total_len = len; + +@@ -1521,6 +1525,8 @@ void ieee802_11_parse_elems_crc(const u8 + kfree(nontransmitted_profile); + + elems->crc = crc; ++ ++ return elems; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch new file mode 100644 index 0000000000..f4906e8c03 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch @@ -0,0 +1,115 @@ +From: Johannes Berg +Date: Fri, 1 Oct 2021 21:11:08 +0200 +Subject: [PATCH] mac80211: fix memory leaks with element parsing + +commit 8223ac199a3849257e86ec27865dc63f034b1cf1 upstream. + +My previous commit 5d24828d05f3 ("mac80211: always allocate +struct ieee802_11_elems") had a few bugs and leaked the new +allocated struct in a few error cases, fix that. + +Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems") +Signed-off-by: Johannes Berg +Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -499,13 +499,14 @@ void ieee80211_process_addba_request(str + elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, + ies_len, true, mgmt->bssid, NULL); + if (!elems || elems->parse_error) +- return; ++ goto free; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, + elems ? elems->addba_ext_ie : NULL); ++free: + kfree(elems); + } + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struc + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, elems); ++ if (elems && !elems->parse_error) ++ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, ++ skb->len, ++ rx_status, ++ elems); + kfree(elems); + break; + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3374,8 +3374,10 @@ static bool ieee80211_assoc_success(stru + bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, + GFP_ATOMIC); + rcu_read_unlock(); +- if (!bss_ies) +- return false; ++ if (!bss_ies) { ++ ret = false; ++ goto out; ++ } + + bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, + false, mgmt->bssid, +@@ -4358,13 +4360,11 @@ void ieee80211_sta_rx_queued_mgmt(struct + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); ++ if (elems && !elems->parse_error) ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); + kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { + struct ieee802_11_elems *elems; +@@ -4384,17 +4384,17 @@ void ieee80211_sta_rx_queued_mgmt(struct + mgmt->u.action.u.ext_chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; ++ if (elems && !elems->parse_error) { ++ /* for the handling code pretend it was an IE */ ++ elems->ext_chansw_ie = ++ &mgmt->u.action.u.ext_chan_switch.data; ++ ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); ++ } + +- /* for the handling code pretend this was also an IE */ +- elems->ext_chansw_ie = +- &mgmt->u.action.u.ext_chan_switch.data; +- +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); + kfree(elems); + } + break; diff --git a/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch b/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch new file mode 100644 index 0000000000..9e1f781367 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch @@ -0,0 +1,41 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 21:56:15 +0200 +Subject: [PATCH] wifi: cfg80211: fix u8 overflow in + cfg80211_update_notlisted_nontrans() + +commit aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d upstream. + +In the copy code of the elements, we do the following calculation +to reach the end of the MBSSID element: + + /* copy the IEs after MBSSID */ + cpy_len = mbssid[1] + 2; + +This looks fine, however, cpy_len is a u8, the same as mbssid[1], +so the addition of two can overflow. In this case the subsequent +memcpy() will overflow the allocated buffer, since it copies 256 +bytes too much due to the way the allocation and memcpy() sizes +are calculated. + +Fix this by using size_t for the cpy_len variable. + +This fixes CVE-2022-41674. + +Reported-by: Soenke Huster +Tested-by: Soenke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2238,7 +2238,7 @@ cfg80211_update_notlisted_nontrans(struc + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; +- u8 cpy_len; ++ size_t cpy_len; + + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + diff --git a/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch b/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch new file mode 100644 index 0000000000..4c8e05e9ba --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch @@ -0,0 +1,47 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:01:37 +0200 +Subject: [PATCH] wifi: cfg80211/mac80211: reject bad MBSSID elements + +commit 8f033d2becc24aa6bfd2a5c104407963560caabc upstream + +Per spec, the maximum value for the MaxBSSID ('n') indicator is 8, +and the minimum is 1 since a multiple BSSID set with just one BSSID +doesn't make sense (the # of BSSIDs is limited by 2^n). + +Limit this in the parsing in both cfg80211 and mac80211, rejecting +any elements with an invalid value. + +This fixes potentially bad shifts in the processing of these inside +the cfg80211_gen_new_bssid() function later. + +I found this during the investigation of CVE-2022-41674 fixed by the +previous patch. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Fixes: 78ac51f81532 ("mac80211: support multi-bssid") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1413,6 +1413,8 @@ static size_t ieee802_11_find_bssid_prof + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { + if (elem->datalen < 2) + continue; ++ if (elem->data[0] < 1 || elem->data[0] > 8) ++ continue; + + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 new_bssid[ETH_ALEN]; +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2103,6 +2103,8 @@ static void cfg80211_parse_mbssid_data(s + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { + if (elem->datalen < 4) + continue; ++ if (elem->data[0] < 1 || (int)elem->data[0] > 8) ++ continue; + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + diff --git a/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch new file mode 100644 index 0000000000..6e97150e90 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch @@ -0,0 +1,94 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:07:15 +0200 +Subject: [PATCH] wifi: mac80211: fix MBSSID parsing use-after-free + +commit ff05d4b45dd89b922578dac497dcabf57cf771c6 + +When we parse a multi-BSSID element, we might point some +element pointers into the allocated nontransmitted_profile. +However, we free this before returning, causing UAF when the +relevant pointers in the parsed elements are accessed. + +Fix this by not allocating the scratch buffer separately but +as part of the returned structure instead, that way, there +are no lifetime issues with it. + +The scratch buffer introduction as part of the returned data +here is taken from MLO feature work done by Ilan. + +This fixes CVE-2022-42719. + +Fixes: 5023b14cf4df ("mac80211: support profile split between elements") +Co-developed-by: Ilan Peer +Signed-off-by: Ilan Peer +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1611,6 +1611,14 @@ struct ieee802_11_elems { + + /* whether a parse error occurred while retrieving these elements */ + bool parse_error; ++ ++ /* ++ * scratch buffer that can be used for various element parsing related ++ * tasks, e.g., element de-fragmentation etc. ++ */ ++ size_t scratch_len; ++ u8 *scratch_pos; ++ u8 scratch[]; + }; + + static inline struct ieee80211_local *hw_to_local( +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1478,24 +1478,25 @@ struct ieee802_11_elems *ieee802_11_pars + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; + +- elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ elems = kzalloc(sizeof(*elems) + len, GFP_ATOMIC); + if (!elems) + return NULL; + elems->ie_start = start; + elems->total_len = len; + +- nontransmitted_profile = kmalloc(len, GFP_ATOMIC); +- if (nontransmitted_profile) { +- nontransmitted_profile_len = +- ieee802_11_find_bssid_profile(start, len, elems, +- transmitter_bssid, +- bss_bssid, +- nontransmitted_profile); +- non_inherit = +- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, +- nontransmitted_profile, +- nontransmitted_profile_len); +- } ++ elems->scratch_len = len; ++ elems->scratch_pos = elems->scratch; ++ ++ nontransmitted_profile = elems->scratch_pos; ++ nontransmitted_profile_len = ++ ieee802_11_find_bssid_profile(start, len, elems, ++ transmitter_bssid, ++ bss_bssid, ++ nontransmitted_profile); ++ non_inherit = ++ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, ++ nontransmitted_profile, ++ nontransmitted_profile_len); + + crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter, + crc, non_inherit); +@@ -1524,8 +1525,6 @@ struct ieee802_11_elems *ieee802_11_pars + offsetofend(struct ieee80211_bssid_index, dtim_count)) + elems->dtim_count = elems->bssid_index->dtim_count; + +- kfree(nontransmitted_profile); +- + elems->crc = crc; + + return elems; diff --git a/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch b/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch new file mode 100644 index 0000000000..da94840dac --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch @@ -0,0 +1,41 @@ +From: Johannes Berg +Date: Thu, 29 Sep 2022 21:50:44 +0200 +Subject: [PATCH] wifi: cfg80211: ensure length byte is present before + access + +commit 567e14e39e8f8c6997a1378bc3be615afca86063 upstream. + +When iterating the elements here, ensure the length byte is +present before checking it to see if the entire element will +fit into the buffer. + +Longer term, we should rewrite this code using the type-safe +element iteration macros that check all of this. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reported-by: Soenke Huster +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -304,7 +304,8 @@ static size_t cfg80211_gen_new_ie(const + tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; + +- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { ++ while (tmp_old + 2 - ie <= ielen && ++ tmp_old + tmp_old[1] + 2 - ie <= ielen) { + if (tmp_old[0] == 0) { + tmp_old++; + continue; +@@ -364,7 +365,8 @@ static size_t cfg80211_gen_new_ie(const + * copied to new ie, skip ssid, capability, bssid-index ie + */ + tmp_new = sub_copy; +- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { ++ while (tmp_new + 2 - sub_copy <= subie_len && ++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { + if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || + tmp_new[0] == WLAN_EID_SSID)) { + memcpy(pos, tmp_new, tmp_new[1] + 2); diff --git a/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch b/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch new file mode 100644 index 0000000000..4680e1e815 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch @@ -0,0 +1,87 @@ +From: Johannes Berg +Date: Fri, 30 Sep 2022 23:44:23 +0200 +Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream. + +There are multiple refcounting bugs related to multi-BSSID: + - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then + the bss pointer is overwritten before checking for the + transmitted BSS, which is clearly wrong. Fix this by using + the bss_from_pub() macro. + + - In cfg80211_bss_update() we copy the transmitted_bss pointer + from tmp into new, but then if we release new, we'll unref + it erroneously. We already set the pointer and ref it, but + need to NULL it since it was copied from the tmp data. + + - In cfg80211_inform_single_bss_data(), if adding to the non- + transmitted list fails, we unlink the BSS and yet still we + return it, but this results in returning an entry without + a reference. We shouldn't return it anyway if it was broken + enough to not get added there. + +This fixes CVE-2022-42720. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cf + lockdep_assert_held(&rdev->bss_lock); + + bss->refcount++; +- if (bss->pub.hidden_beacon_bss) { +- bss = container_of(bss->pub.hidden_beacon_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } +- if (bss->pub.transmitted_bss) { +- bss = container_of(bss->pub.transmitted_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } ++ ++ if (bss->pub.hidden_beacon_bss) ++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; ++ ++ if (bss->pub.transmitted_bss) ++ bss_from_pub(bss->pub.transmitted_bss)->refcount++; + } + + static inline void bss_ref_put(struct cfg80211_registered_device *rdev, +@@ -1743,6 +1737,8 @@ cfg80211_bss_update(struct cfg80211_regi + new->refcount = 1; + INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); ++ /* we'll set this later if it was non-NULL */ ++ new->pub.transmitted_bss = NULL; + + if (rcu_access_pointer(tmp->pub.proberesp_ies)) { + hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); +@@ -1983,10 +1979,15 @@ cfg80211_inform_single_bss_data(struct w + spin_lock_bh(&rdev->bss_lock); + if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, + &res->pub)) { +- if (__cfg80211_unlink_bss(rdev, res)) ++ if (__cfg80211_unlink_bss(rdev, res)) { + rdev->bss_generation++; ++ res = NULL; ++ } + } + spin_unlock_bh(&rdev->bss_lock); ++ ++ if (!res) ++ return NULL; + } + + trace_cfg80211_return_bss(&res->pub); diff --git a/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch b/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch new file mode 100644 index 0000000000..db0e51edc2 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch @@ -0,0 +1,48 @@ +From: Johannes Berg +Date: Sat, 1 Oct 2022 00:01:44 +0200 +Subject: [PATCH] wifi: cfg80211: avoid nontransmitted BSS list + corruption +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit bcca852027e5878aec911a347407ecc88d6fff7f upstream. + +If a non-transmitted BSS shares enough information (both +SSID and BSSID!) with another non-transmitted BSS of a +different AP, then we can find and update it, and then +try to add it to the non-transmitted BSS list. We do a +search for it on the transmitted BSS, but if it's not +there (but belongs to another transmitted BSS), the list +gets corrupted. + +Since this is an erroneous situation, simply fail the +list insertion in this case and free the non-transmitted +BSS. + +This fixes CVE-2022-42721. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -425,6 +425,15 @@ cfg80211_add_nontrans_list(struct cfg802 + + rcu_read_unlock(); + ++ /* ++ * This is a bit weird - it's not on the list, but already on another ++ * one! The only way that could happen is if there's some BSSID/SSID ++ * shared by multiple APs in their multi-BSSID profiles, potentially ++ * with hidden SSID mixed in ... ignore it. ++ */ ++ if (!list_empty(&nontrans_bss->nontrans_list)) ++ return -EINVAL; ++ + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; diff --git a/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch b/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch new file mode 100644 index 0000000000..ed834ff296 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch @@ -0,0 +1,31 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 15:10:09 +0200 +Subject: [PATCH] wifi: mac80211_hwsim: avoid mac80211 warning on bad + rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 1833b6f46d7e2830251a063935ab464256defe22 upstream. + +If the tool on the other side (e.g. wmediumd) gets confused +about the rate, we hit a warning in mac80211. Silence that +by effectively duplicating the check here and dropping the +frame silently (in mac80211 it's dropped with the warning). + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Signed-off-by: Johannes Berg +--- + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -3760,6 +3760,8 @@ static int hwsim_cloned_frame_received_n + + rx_status.band = channel->band; + rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); ++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates) ++ goto out; + rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + hdr = (void *)skb->data; diff --git a/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch b/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch new file mode 100644 index 0000000000..44b8729977 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch @@ -0,0 +1,52 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 21:24:10 +0200 +Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for + P2P-device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit b2d03cabe2b2e150ff5a381731ea0355459be09f upstream. + +If beacon protection is active but the beacon cannot be +decrypted or is otherwise malformed, we call the cfg80211 +API to report this to userspace, but that uses a netdev +pointer, which isn't present for P2P-Device. Fix this to +call it only conditionally to ensure cfg80211 won't crash +in the case of P2P-Device. + +This fixes CVE-2022-42722. + +Reported-by: Sönke Huster +Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space") +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1986,10 +1986,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_ + + if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || + mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + +- NUM_DEFAULT_BEACON_KEYS) { +- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +- skb->data, +- skb->len); ++ NUM_DEFAULT_BEACON_KEYS) { ++ if (rx->sdata->dev) ++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, ++ skb->data, ++ skb->len); + return RX_DROP_MONITOR; /* unexpected BIP keyidx */ + } + +@@ -2137,7 +2138,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_ + /* either the frame has been decrypted or will be dropped */ + status->flag |= RX_FLAG_DECRYPTED; + +- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) ++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE && ++ rx->sdata->dev)) + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, + skb->data, skb->len); + diff --git a/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch b/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch new file mode 100644 index 0000000000..c689fac854 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch @@ -0,0 +1,85 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 23:11:43 +0200 +Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit c90b93b5b782891ebfda49d4e5da36632fefd5d1 upstream. + +When updating beacon elements in a non-transmitted BSS, +also update the hidden sub-entries to the same beacon +elements, so that a future update through other paths +won't trigger a WARN_ON(). + +The warning is triggered because the beacon elements in +the hidden BSSes that are children of the BSS should +always be the same as in the parent. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -1609,6 +1609,23 @@ struct cfg80211_non_tx_bss { + u8 bssid_index; + }; + ++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known, ++ const struct cfg80211_bss_ies *new_ies, ++ const struct cfg80211_bss_ies *old_ies) ++{ ++ struct cfg80211_internal_bss *bss; ++ ++ /* Assign beacon IEs to all sub entries */ ++ list_for_each_entry(bss, &known->hidden_list, hidden_list) { ++ const struct cfg80211_bss_ies *ies; ++ ++ ies = rcu_access_pointer(bss->pub.beacon_ies); ++ WARN_ON(ies != old_ies); ++ ++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies); ++ } ++} ++ + static bool + cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *known, +@@ -1632,7 +1649,6 @@ cfg80211_update_known_bss(struct cfg8021 + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } else if (rcu_access_pointer(new->pub.beacon_ies)) { + const struct cfg80211_bss_ies *old; +- struct cfg80211_internal_bss *bss; + + if (known->pub.hidden_beacon_bss && + !list_empty(&known->hidden_list)) { +@@ -1660,16 +1676,7 @@ cfg80211_update_known_bss(struct cfg8021 + if (old == rcu_access_pointer(known->pub.ies)) + rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies); + +- /* Assign beacon IEs to all sub entries */ +- list_for_each_entry(bss, &known->hidden_list, hidden_list) { +- const struct cfg80211_bss_ies *ies; +- +- ies = rcu_access_pointer(bss->pub.beacon_ies); +- WARN_ON(ies != old); +- +- rcu_assign_pointer(bss->pub.beacon_ies, +- new->pub.beacon_ies); +- } ++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old); + + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); +@@ -2319,6 +2326,8 @@ cfg80211_update_notlisted_nontrans(struc + } else { + old = rcu_access_pointer(nontrans_bss->beacon_ies); + rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); ++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss), ++ new_ies, old); + rcu_assign_pointer(nontrans_bss->ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); diff --git a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch index 0e58b61602..50b6b94fbf 100644 --- a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch +++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch @@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c -@@ -461,16 +461,19 @@ static void __ieee80211_scan_completed(s +@@ -465,16 +465,19 @@ static void __ieee80211_scan_completed(s scan_req = rcu_dereference_protected(local->scan_req, lockdep_is_held(&local->mtx)); diff --git a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch b/package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch similarity index 96% rename from package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch rename to package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch index 1e3486accd..edee4b3ee0 100644 --- a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch +++ b/package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch @@ -56,7 +56,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -3180,6 +3180,49 @@ static void ieee80211_process_sa_query_r +@@ -3182,6 +3182,49 @@ static void ieee80211_process_sa_query_r ieee80211_tx_skb(sdata, skb); } @@ -106,7 +106,7 @@ Signed-off-by: Johannes Berg static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) { -@@ -3205,6 +3248,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 +@@ -3207,6 +3250,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { int sig = 0; From 88803cb0e6e42ea00bd7c3dc8838e660239d3f16 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Oct 2022 12:11:10 +0200 Subject: [PATCH 06/26] mac80211: add patch that gives the driver more control over netdev offloads This can be used to selectively disable checksum, SG or GSO offloads Signed-off-by: Felix Fietkau --- ...port-for-restricting-netdev-features.patch | 513 ++++++++++++++++++ 1 file changed, 513 insertions(+) create mode 100644 package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch diff --git a/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch new file mode 100644 index 0000000000..d133ed91eb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch @@ -0,0 +1,513 @@ +From: Felix Fietkau +Date: Sun, 9 Oct 2022 20:15:46 +0200 +Subject: [PATCH] mac80211: add support for restricting netdev features per vif + +This can be used to selectively disable feature flags for checksum offload, +scatter/gather or GSO by changing vif->netdev_features. +Removing features from vif->netdev_features does not affect the netdev +features themselves, but instead fixes up skbs in the tx path so that the +offloads are not needed in the driver. + +Aside from making it easier to deal with vif type based hardware limitations, +this also makes it possible to optimize performance on hardware without native +GSO support by declaring GSO support in hw->netdev_features and removing it +from vif->netdev_features. This allows mac80211 to handle GSO segmentation +after the sta lookup, but before itxq enqueue, thus reducing the number of +unnecessary sta lookups, as well as some other per-packet processing. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/fq_impl.h ++++ b/include/net/fq_impl.h +@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq + fq_skb_free_t free_func) + { + struct fq_flow *flow; ++ struct sk_buff *next; + bool oom; + + lockdep_assert_held(&fq->lock); +@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq + } + + flow->tin = tin; +- flow->backlog += skb->len; +- tin->backlog_bytes += skb->len; +- tin->backlog_packets++; +- fq->memory_usage += skb->truesize; +- fq->backlog++; ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ flow->backlog += skb->len; ++ tin->backlog_bytes += skb->len; ++ tin->backlog_packets++; ++ fq->memory_usage += skb->truesize; ++ fq->backlog++; ++ __skb_queue_tail(&flow->queue, skb); ++ } + + if (list_empty(&flow->flowchain)) { + flow->deficit = fq->quantum; +@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq + &tin->new_flows); + } + +- __skb_queue_tail(&flow->queue, skb); + oom = (fq->memory_usage > fq->memory_limit); + while (fq->backlog > fq->limit || oom) { + flow = fq_find_fattest_flow(fq); +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1685,6 +1685,10 @@ enum ieee80211_offload_flags { + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. + * @mu_mimo_owner: indicates interface owns MU-MIMO capability ++ * @netdev_features: tx netdev features supported by the hardware for this ++ * vif. mac80211 initializes this to hw->netdev_features, and the driver ++ * can mask out specific tx features. mac80211 will handle software fixup ++ * for masked offloads (GSO, CSUM) + * @driver_flags: flags/capabilities the driver has for this interface, + * these need to be set (or cleared) when the interface is added + * or, if supported by the driver, the interface type is changed +@@ -1736,6 +1740,7 @@ struct ieee80211_vif { + + struct ieee80211_chanctx_conf __rcu *chanctx_conf; + ++ netdev_features_t netdev_features; + u32 driver_flags; + u32 offload_flags; + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -2209,6 +2209,7 @@ int ieee80211_if_add(struct ieee80211_lo + ndev->features |= local->hw.netdev_features; + ndev->hw_features |= ndev->features & + MAC80211_SUPPORTED_FEATURES_TX; ++ sdata->vif.netdev_features = local->hw.netdev_features; + + netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1310,7 +1310,11 @@ static struct txq_info *ieee80211_get_tx + + static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) + { +- IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); ++ struct sk_buff *next; ++ codel_time_t now = codel_get_time(); ++ ++ skb_list_walk_safe(skb, skb, next) ++ IEEE80211_SKB_CB(skb)->control.enqueue_time = now; + } + + static u32 codel_skb_len_func(const struct sk_buff *skb) +@@ -3499,47 +3503,71 @@ ieee80211_xmit_fast_finish(struct ieee80 + return TX_CONTINUE; + } + +-static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, +- struct sta_info *sta, +- struct ieee80211_fast_tx *fast_tx, +- struct sk_buff *skb) ++static netdev_features_t ++ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata) + { +- struct ieee80211_local *local = sdata->local; +- u16 ethertype = (skb->data[12] << 8) | skb->data[13]; +- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); +- int hw_headroom = sdata->local->hw.extra_tx_headroom; +- struct ethhdr eth; +- struct ieee80211_tx_info *info; +- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; +- struct ieee80211_tx_data tx; +- ieee80211_tx_result r; +- struct tid_ampdu_tx *tid_tx = NULL; +- u8 tid = IEEE80211_NUM_TIDS; ++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) ++ return sdata->vif.netdev_features; + +- /* control port protocol needs a lot of special handling */ +- if (cpu_to_be16(ethertype) == sdata->control_port_protocol) +- return false; ++ if (!sdata->bss) ++ return 0; + +- /* only RFC 1042 SNAP */ +- if (ethertype < ETH_P_802_3_MIN) +- return false; ++ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); ++ return sdata->vif.netdev_features; ++} + +- /* don't handle TX status request here either */ +- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) +- return false; ++static struct sk_buff * ++ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) ++{ ++ if (skb_is_gso(skb)) { ++ struct sk_buff *segs; + +- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { +- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); +- if (tid_tx) { +- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) +- return false; +- if (tid_tx->timeout) +- tid_tx->last_tx = jiffies; +- } ++ segs = skb_gso_segment(skb, features); ++ if (!segs) ++ return skb; ++ if (IS_ERR(segs)) ++ goto free; ++ ++ consume_skb(skb); ++ return segs; ++ } ++ ++ if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) ++ goto free; ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ int ofs = skb_checksum_start_offset(skb); ++ ++ if (skb->encapsulation) ++ skb_set_inner_transport_header(skb, ofs); ++ else ++ skb_set_transport_header(skb, ofs); ++ ++ if (skb_csum_hwoffload_help(skb, features)) ++ goto free; + } + +- /* after this point (skb is modified) we cannot return false */ ++ skb_mark_not_on_list(skb); ++ return skb; ++ ++free: ++ kfree_skb(skb); ++ return NULL; ++} ++ ++static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct ieee80211_fast_tx *fast_tx, ++ struct sk_buff *skb, u8 tid, bool ampdu) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; ++ struct ieee80211_tx_info *info; ++ struct ieee80211_tx_data tx; ++ ieee80211_tx_result r; ++ int hw_headroom = sdata->local->hw.extra_tx_headroom; ++ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); ++ struct ethhdr eth; + + if (skb_shared(skb)) { + struct sk_buff *tmp_skb = skb; +@@ -3548,12 +3576,12 @@ static bool ieee80211_xmit_fast(struct i + kfree_skb(tmp_skb); + + if (!skb) +- return true; ++ return; + } + + if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && + ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) +- return true; ++ return; + + /* will not be crypto-handled beyond what we do here, so use false + * as the may-encrypt argument for the resize to not account for +@@ -3562,10 +3590,8 @@ static bool ieee80211_xmit_fast(struct i + if (unlikely(ieee80211_skb_resize(sdata, skb, + max_t(int, extra_head + hw_headroom - + skb_headroom(skb), 0), +- ENCRYPT_NO))) { +- kfree_skb(skb); +- return true; +- } ++ ENCRYPT_NO))) ++ goto free; + + memcpy(ð, skb->data, ETH_HLEN - 2); + hdr = skb_push(skb, extra_head); +@@ -3579,7 +3605,7 @@ static bool ieee80211_xmit_fast(struct i + info->control.vif = &sdata->vif; + info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | + IEEE80211_TX_CTL_DONTFRAG | +- (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); ++ (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); + info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; + + #ifdef CPTCFG_MAC80211_DEBUGFS +@@ -3601,16 +3627,14 @@ static bool ieee80211_xmit_fast(struct i + tx.key = fast_tx->key; + + if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; ++ return; + + tx.skb = skb; + r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, + fast_tx->key, &tx); + tx.skb = NULL; +- if (r == TX_DROP) { +- kfree_skb(skb); +- return true; +- } ++ if (r == TX_DROP) ++ goto free; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, +@@ -3618,6 +3642,55 @@ static bool ieee80211_xmit_fast(struct i + + __skb_queue_tail(&tx.skbs, skb); + ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); ++ return; ++ ++free: ++ kfree_skb(skb); ++} ++ ++static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct ieee80211_fast_tx *fast_tx, ++ struct sk_buff *skb) ++{ ++ u16 ethertype = (skb->data[12] << 8) | skb->data[13]; ++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; ++ struct tid_ampdu_tx *tid_tx = NULL; ++ struct sk_buff *next; ++ u8 tid = IEEE80211_NUM_TIDS; ++ ++ /* control port protocol needs a lot of special handling */ ++ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) ++ return false; ++ ++ /* only RFC 1042 SNAP */ ++ if (ethertype < ETH_P_802_3_MIN) ++ return false; ++ ++ /* don't handle TX status request here either */ ++ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) ++ return false; ++ ++ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); ++ if (tid_tx) { ++ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) ++ return false; ++ if (tid_tx->timeout) ++ tid_tx->last_tx = jiffies; ++ } ++ } ++ ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ if (!skb) ++ return true; ++ ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); ++ } ++ + return true; + } + +@@ -4123,31 +4196,14 @@ void __ieee80211_subif_start_xmit(struct + goto out; + } + +- if (skb_is_gso(skb)) { +- struct sk_buff *segs; +- +- segs = skb_gso_segment(skb, 0); +- if (IS_ERR(segs)) { +- goto out_free; +- } else if (segs) { +- consume_skb(skb); +- skb = segs; +- } +- } else { +- /* we cannot process non-linear frames on this path */ +- if (skb_linearize(skb)) +- goto out_free; +- +- /* the frame could be fragmented, software-encrypted, and other +- * things so we cannot really handle checksum offload with it - +- * fix it up in software before we handle anything else. +- */ +- if (skb->ip_summed == CHECKSUM_PARTIAL) { +- skb_set_transport_header(skb, +- skb_checksum_start_offset(skb)); +- if (skb_checksum_help(skb)) +- goto out_free; +- } ++ /* the frame could be fragmented, software-encrypted, and other ++ * things so we cannot really handle checksum or GSO offload. ++ * fix it up in software before we handle anything else. ++ */ ++ skb = ieee80211_tx_skb_fixup(skb, 0); ++ if (!skb) { ++ len = 0; ++ goto out; + } + + skb_list_walk_safe(skb, skb, next) { +@@ -4310,9 +4366,11 @@ netdev_tx_t ieee80211_subif_start_xmit(s + return NETDEV_TX_OK; + } + +-static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, +- struct sk_buff *skb, struct sta_info *sta, +- bool txpending) ++ ++ ++static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct sta_info *sta, ++ bool txpending) + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_tx_control control = {}; +@@ -4321,14 +4379,6 @@ static bool ieee80211_tx_8023(struct iee + unsigned long flags; + int q = info->hw_queue; + +- if (sta) +- sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); +- +- ieee80211_tpt_led_trig_tx(local, skb->len); +- +- if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; +- + spin_lock_irqsave(&local->queue_stop_reason_lock, flags); + + if (local->queue_stop_reasons[q] || +@@ -4355,27 +4405,50 @@ static bool ieee80211_tx_8023(struct iee + return true; + } + ++static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct sta_info *sta, ++ bool txpending) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct sk_buff *next; ++ bool ret = true; ++ ++ if (ieee80211_queue_skb(local, sdata, sta, skb)) ++ return true; ++ ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) ++ ret = false; ++ } ++ ++ return ret; ++} ++ + static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, + struct net_device *dev, struct sta_info *sta, + struct ieee80211_key *key, struct sk_buff *skb) + { +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_tx_info *info; + struct ieee80211_local *local = sdata->local; + struct tid_ampdu_tx *tid_tx; ++ struct sk_buff *seg, *next; ++ unsigned int skbs = 0, len = 0; ++ u16 queue; + u8 tid; + + if (local->ops->wake_tx_queue) { +- u16 queue = __ieee80211_select_queue(sdata, sta, skb); ++ queue = __ieee80211_select_queue(sdata, sta, skb); + skb_set_queue_mapping(skb, queue); + skb_get_hash(skb); ++ } else { ++ queue = skb_get_queue_mapping(skb); + } + + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && + test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) + goto out_free; + +- memset(info, 0, sizeof(*info)); +- + ieee80211_aggr_check(sdata, sta, skb); + + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +@@ -4387,22 +4460,20 @@ static void ieee80211_8023_xmit(struct i + return; + } + +- info->flags |= IEEE80211_TX_CTL_AMPDU; + if (tid_tx->timeout) + tid_tx->last_tx = jiffies; + } + +- if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) +- info->ack_frame_id = ieee80211_store_ack_skb(local, skb, +- &info->flags, NULL); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ if (!skb) ++ return; + +- info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ if (tid_tx) ++ info->flags |= IEEE80211_TX_CTL_AMPDU; + +- dev_sw_netstats_tx_add(dev, 1, skb->len); +- +- sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; +- sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; ++ info->hw_queue = sdata->vif.hw_queue[queue]; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, +@@ -4414,6 +4485,24 @@ static void ieee80211_8023_xmit(struct i + if (key) + info->control.hw_key = &key->conf; + ++ skb_list_walk_safe(skb, seg, next) { ++ skbs++; ++ len += seg->len; ++ if (seg != skb) ++ memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); ++ } ++ ++ if (unlikely(skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ info->ack_frame_id = ieee80211_store_ack_skb(local, skb, ++ &info->flags, NULL); ++ ++ dev_sw_netstats_tx_add(dev, skbs, len); ++ sta->tx_stats.packets[queue] += skbs; ++ sta->tx_stats.bytes[queue] += len; ++ ++ ieee80211_tpt_led_trig_tx(local, len); ++ + ieee80211_tx_8023(sdata, skb, sta, false); + + return; +@@ -4455,6 +4544,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) + goto skip_offload; + ++ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + goto out; + From 2f8ac8bcea879542b2bc414a108c3aff166d5ef5 Mon Sep 17 00:00:00 2001 From: Huangbin Zhan Date: Wed, 30 Mar 2022 00:15:29 +0800 Subject: [PATCH 07/26] build: image: use printf for ModelNameLimit16 Fix syntax error on macos, for substr is undefined results according to the POSIX standard. From expr on macos: According to the POSIX standard, the use of string arguments length, substr, index, or match produces undefined results. In this version of expr, these arguments are treated just as their respective string values. By a simple test Makefile: define ModelNameLimit16 $(shell expr substr "$(word 2, $(subst _, ,$(1)))" 1 16) endef define ModelNameLimit16_2 $(shell printf %.16s "$(word 2, $(subst _, ,$(1)))") endef hello: echo $(call ModelNameLimit16, technicolor_tg582n-telecom-italia) echo $(call ModelNameLimit16_2, technicolor_tg582n-telecom-italia) The same output is produced. echo tg582n-telecom-i tg582n-telecom-i echo tg582n-telecom-i tg582n-telecom-i Signed-off-by: Huangbin Zhan [ wrap commit description to 80 columns and improve it ] Signed-off-by: Christian Marangi --- include/image-commands.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/image-commands.mk b/include/image-commands.mk index 6fe2890a1a..6b4bc4945c 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -4,7 +4,7 @@ IMAGE_KERNEL = $(word 1,$^) IMAGE_ROOTFS = $(word 2,$^) define ModelNameLimit16 -$(shell expr substr "$(word 2, $(subst _, ,$(1)))" 1 16) +$(shell printf %.16s "$(word 2, $(subst _, ,$(1)))") endef define rootfs_align From 41a1a652fbd407a40d55a07bccdbc92770a4c2be Mon Sep 17 00:00:00 2001 From: Olliver Schinagl Date: Sun, 4 Sep 2022 22:08:47 +0200 Subject: [PATCH 08/26] kernel: backport gnu11 upgrade Upstream has switched to gnu11 not too long ago. One advantage of backporting this to these older kernels is, that we can encourage and write better upstreamable kernels. E.g. the kernel devs prefer loop declarations. Shrinking the master/local gap will be useful in these cases. Signed-off-by: Olliver Schinagl Acked-by: Christian Marangi --- ...ild-use-Wdeclaration-after-statement.patch | 73 +++++++++++++++++ ...05-v5.17-02-Kbuild-move-to-std-gnu11.patch | 60 ++++++++++++++ ...-use-std-gnu11-for-KBUILD_USERCFLAGS.patch | 42 ++++++++++ ...ild-use-Wdeclaration-after-statement.patch | 81 +++++++++++++++++++ ...05-v5.17-02-Kbuild-move-to-std-gnu11.patch | 64 +++++++++++++++ ...-use-std-gnu11-for-KBUILD_USERCFLAGS.patch | 47 +++++++++++ 6 files changed, 367 insertions(+) create mode 100644 target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch create mode 100644 target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch create mode 100644 target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch create mode 100644 target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch create mode 100644 target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch create mode 100644 target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch diff --git a/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch new file mode 100644 index 0000000000..dd8a1b445d --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch @@ -0,0 +1,73 @@ +From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Tue, 8 Mar 2022 22:56:13 +0100 +Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement + +The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting +the use of additional C11 features such as for-loop initial declarations. + +One contentious aspect of C99 is that it permits mixed declarations and +code, and for now at least, it seems preferable to enforce that +declarations must come first. + +These warnings were already enabled in the kernel itself, but not +for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses +a separate set of CFLAGS. + +This patch fixes an existing violation in modpost.c, which is not +reported because of the missing flag in KBUILD_USERCFLAGS: + +| scripts/mod/modpost.c: In function ‘match’: +| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] +| 837 | const char *endp = p + strlen(p) - 1; +| | ^~~~~ + +Signed-off-by: Mark Rutland +[arnd: don't add a duplicate flag to the default set, update changelog] +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) +Signed-off-by: Masahiro Yamada +--- + Makefile | 3 ++- + arch/arm64/kernel/vdso32/Makefile | 1 + + scripts/mod/modpost.c | 4 +++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,8 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 ++ -O2 -fomit-frame-pointer -std=gnu89 \ ++ -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + + KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) +--- a/arch/arm64/kernel/vdso32/Makefile ++++ b/arch/arm64/kernel/vdso32/Makefile +@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-pr + -fno-strict-aliasing -fno-common \ + -Werror-implicit-function-declaration \ + -Wno-format-security \ ++ -Wdeclaration-after-statement \ + -std=gnu89 + VDSO_CFLAGS += -O2 + # Some useful compiler-dependent flags from top-level Makefile +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -844,8 +844,10 @@ static int match(const char *sym, const + { + const char *p; + while (*pat) { ++ const char *endp; ++ + p = *pat++; +- const char *endp = p + strlen(p) - 1; ++ endp = p + strlen(p) - 1; + + /* "*foo*" */ + if (*p == '*' && *endp == '*') { diff --git a/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch new file mode 100644 index 0000000000..7938fe5026 --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch @@ -0,0 +1,60 @@ +From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:14 +0100 +Subject: [PATCH 2/3] Kbuild: move to -std=gnu11 + +During a patch discussion, Linus brought up the option of changing +the C standard version from gnu89 to gnu99, which allows using variable +declaration inside of a for() loop. While the C99, C11 and later standards +introduce many other features, most of these are already available in +gnu89 as GNU extensions as well. + +An earlier attempt to do this when gcc-5 started defaulting to +-std=gnu11 failed because at the time that caused warnings about +designated initializers with older compilers. Now that gcc-5.1 is +the minimum compiler version used for building kernels, that is no +longer a concern. Similarly, the behavior of 'inline' functions changes +between gnu89 using gnu_inline behavior and gnu11 using standard c99+ +behavior, but this was taken care of by defining 'inline' to include +__attribute__((gnu_inline)) in order to allow building with clang a +while ago. + +Nathan Chancellor reported a new -Wdeclaration-after-statement +warning that appears in a system header on arm, this still needs a +workaround. + +The differences between gnu99, gnu11, gnu1x and gnu17 are fairly +minimal and mainly impact warnings at the -Wpedantic level that the +kernel never enables. Between these, gnu11 is the newest version +that is supported by all supported compiler versions, though it is +only the default on gcc-5, while all other supported versions of +gcc or clang default to gnu1x/gnu17. + +Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/ +Link: https://github.com/ClangBuiltLinux/linux/issues/1603 +Suggested-by: Linus Torvalds +Acked-by: Marco Elver +Acked-by: Jani Nikula +Acked-by: David Sterba +Tested-by: Sedat Dilek +Reviewed-by: Alex Shi +Reviewed-by: Nick Desaulniers +Reviewed-by: Miguel Ojeda +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Makefile ++++ b/Makefile +@@ -498,7 +498,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ + -Werror=return-type -Wno-format-security \ +- -std=gnu89 ++ -std=gnu11 + KBUILD_CPPFLAGS := -D__KERNEL__ + KBUILD_AFLAGS_KERNEL := + KBUILD_CFLAGS_KERNEL := diff --git a/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch new file mode 100644 index 0000000000..34b5b653ae --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch @@ -0,0 +1,42 @@ +From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:15 +0100 +Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS + +As we change the C language standard for the kernel from gnu89 to +gnu11, it makes sense to also update the version for user space +compilation. + +Some users have older native compilers than what they use for +kernel builds, so I considered using gnu99 as the default version +for wider compatibility with gcc-4.6 and earlier. + +However, testing with older compilers showed that we already require +HOSTCC version 5.1 as well because a lot of host tools include +linux/compiler.h that uses __has_attribute(): + + CC tools/objtool/exec-cmd.o +In file included from tools/include/linux/compiler_types.h:36:0, + from tools/include/linux/compiler.h:5, + from exec-cmd.c:2: +tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef] + +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,7 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 \ ++ -O2 -fomit-frame-pointer -std=gnu11 \ + -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := diff --git a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch new file mode 100644 index 0000000000..141a7a18c5 --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch @@ -0,0 +1,81 @@ +From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Tue, 8 Mar 2022 22:56:13 +0100 +Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement + +The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting +the use of additional C11 features such as for-loop initial declarations. + +One contentious aspect of C99 is that it permits mixed declarations and +code, and for now at least, it seems preferable to enforce that +declarations must come first. + +These warnings were already enabled in the kernel itself, but not +for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses +a separate set of CFLAGS. + +This patch fixes an existing violation in modpost.c, which is not +reported because of the missing flag in KBUILD_USERCFLAGS: + +| scripts/mod/modpost.c: In function ‘match’: +| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] +| 837 | const char *endp = p + strlen(p) - 1; +| | ^~~~~ + +Signed-off-by: Mark Rutland +[arnd: don't add a duplicate flag to the default set, update changelog] +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) +Signed-off-by: Masahiro Yamada +--- + Makefile | 3 ++- + arch/arm64/kernel/vdso32/Makefile | 1 + + scripts/mod/modpost.c | 4 +++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index b9e0b5c604af..cfe400032f96 100644 +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,8 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 ++ -O2 -fomit-frame-pointer -std=gnu89 \ ++ -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + + KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) +diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile +index abad38c576e1..33cd7ed3f94f 100644 +--- a/arch/arm64/kernel/vdso32/Makefile ++++ b/arch/arm64/kernel/vdso32/Makefile +@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common \ + -Werror-implicit-function-declaration \ + -Wno-format-security \ ++ -Wdeclaration-after-statement \ + -std=gnu89 + VDSO_CFLAGS += -O2 + # Some useful compiler-dependent flags from top-level Makefile +diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c +index 3c27a177b28b..d2b17ed27e6e 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -844,8 +844,10 @@ static int match(const char *sym, const char * const pat[]) + { + const char *p; + while (*pat) { ++ const char *endp; ++ + p = *pat++; +- const char *endp = p + strlen(p) - 1; ++ endp = p + strlen(p) - 1; + + /* "*foo*" */ + if (*p == '*' && *endp == '*') { +-- +2.37.2 diff --git a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch new file mode 100644 index 0000000000..79bda0cd7e --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch @@ -0,0 +1,64 @@ +From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:14 +0100 +Subject: [PATCH 2/3] Kbuild: move to -std=gnu11 + +During a patch discussion, Linus brought up the option of changing +the C standard version from gnu89 to gnu99, which allows using variable +declaration inside of a for() loop. While the C99, C11 and later standards +introduce many other features, most of these are already available in +gnu89 as GNU extensions as well. + +An earlier attempt to do this when gcc-5 started defaulting to +-std=gnu11 failed because at the time that caused warnings about +designated initializers with older compilers. Now that gcc-5.1 is +the minimum compiler version used for building kernels, that is no +longer a concern. Similarly, the behavior of 'inline' functions changes +between gnu89 using gnu_inline behavior and gnu11 using standard c99+ +behavior, but this was taken care of by defining 'inline' to include +__attribute__((gnu_inline)) in order to allow building with clang a +while ago. + +Nathan Chancellor reported a new -Wdeclaration-after-statement +warning that appears in a system header on arm, this still needs a +workaround. + +The differences between gnu99, gnu11, gnu1x and gnu17 are fairly +minimal and mainly impact warnings at the -Wpedantic level that the +kernel never enables. Between these, gnu11 is the newest version +that is supported by all supported compiler versions, though it is +only the default on gcc-5, while all other supported versions of +gcc or clang default to gnu1x/gnu17. + +Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/ +Link: https://github.com/ClangBuiltLinux/linux/issues/1603 +Suggested-by: Linus Torvalds +Acked-by: Marco Elver +Acked-by: Jani Nikula +Acked-by: David Sterba +Tested-by: Sedat Dilek +Reviewed-by: Alex Shi +Reviewed-by: Nick Desaulniers +Reviewed-by: Miguel Ojeda +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index cfe400032f96..fe86758acaaa 100644 +--- a/Makefile ++++ b/Makefile +@@ -498,7 +498,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ + -Werror=return-type -Wno-format-security \ +- -std=gnu89 ++ -std=gnu11 + KBUILD_CPPFLAGS := -D__KERNEL__ + KBUILD_AFLAGS_KERNEL := + KBUILD_CFLAGS_KERNEL := +-- +2.37.2 diff --git a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch new file mode 100644 index 0000000000..f60daa3800 --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch @@ -0,0 +1,47 @@ +From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:15 +0100 +Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS + +As we change the C language standard for the kernel from gnu89 to +gnu11, it makes sense to also update the version for user space +compilation. + +Some users have older native compilers than what they use for +kernel builds, so I considered using gnu99 as the default version +for wider compatibility with gcc-4.6 and earlier. + +However, testing with older compilers showed that we already require +HOSTCC version 5.1 as well because a lot of host tools include +linux/compiler.h that uses __has_attribute(): + + CC tools/objtool/exec-cmd.o +In file included from tools/include/linux/compiler_types.h:36:0, + from tools/include/linux/compiler.h:5, + from exec-cmd.c:2: +tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef] + +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index fe86758acaaa..e569fccfb009 100644 +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,7 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 \ ++ -O2 -fomit-frame-pointer -std=gnu11 \ + -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + +-- +2.37.2 From 3413409ef66972073a81f61bd4c46ec55e93f50f Mon Sep 17 00:00:00 2001 From: Aleksey Nasibulin Date: Thu, 13 Oct 2022 08:22:53 +0000 Subject: [PATCH 09/26] bcm53xx: linksys ea6500-v2: extend RAM to full 256MB Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB. Expand the definition to use all the available RAM. Signed-off-by: Aleksey Nasibulin [ wrap to 80 columns ] Signed-off-by: Christian Marangi --- ...-Extend-RAM-to-full-256MB-for-Linksy.patch | 32 +++++++++++++++++++ ...-Extend-RAM-to-full-256MB-for-Linksy.patch | 32 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch create mode 100644 target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch diff --git a/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch b/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch new file mode 100644 index 0000000000..8d15abf915 --- /dev/null +++ b/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch @@ -0,0 +1,32 @@ +From e492f69e4da879db7b3e9a2290e5b6620f1335b5 Mon Sep 17 00:00:00 2001 +From: Aleksey Nasibulin +Date: Thu, 13 Oct 2022 08:16:51 +0000 +Subject: [PATCH] ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys + EA6500 V2 + +Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB. +Expand the definition to use all the available RAM. + +Fixes: 03e96644d7a8 ("ARM: dts: BCM5301X: Add basic DT for Linksys EA6500 V2") +Signed-off-by: Aleksey Nasibulin +--- + arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +index f1412ba83def..0454423fe166 100644 +--- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts ++++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +@@ -19,7 +19,8 @@ chosen { + + memory@0 { + device_type = "memory"; +- reg = <0x00000000 0x08000000>; ++ reg = <0x00000000 0x08000000>, ++ <0x88000000 0x08000000>; + }; + + gpio-keys { +-- +2.30.2 + diff --git a/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch b/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch new file mode 100644 index 0000000000..8d15abf915 --- /dev/null +++ b/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch @@ -0,0 +1,32 @@ +From e492f69e4da879db7b3e9a2290e5b6620f1335b5 Mon Sep 17 00:00:00 2001 +From: Aleksey Nasibulin +Date: Thu, 13 Oct 2022 08:16:51 +0000 +Subject: [PATCH] ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys + EA6500 V2 + +Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB. +Expand the definition to use all the available RAM. + +Fixes: 03e96644d7a8 ("ARM: dts: BCM5301X: Add basic DT for Linksys EA6500 V2") +Signed-off-by: Aleksey Nasibulin +--- + arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +index f1412ba83def..0454423fe166 100644 +--- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts ++++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +@@ -19,7 +19,8 @@ chosen { + + memory@0 { + device_type = "memory"; +- reg = <0x00000000 0x08000000>; ++ reg = <0x00000000 0x08000000>, ++ <0x88000000 0x08000000>; + }; + + gpio-keys { +-- +2.30.2 + From e5cab973a4b5ad1a10787b2312129b346f3a581a Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Sat, 8 Jan 2022 08:55:21 +0100 Subject: [PATCH 10/26] hostapd: add measurement report value for beacon reports Add the measurement report value to the beacon reports send via ubus. It is possible to derive from the measurement report if a station refused to do a beacon report and why. It is important to know why a station refuses to do a beacon-report. In particular, we should not request a beacon report from a station again that refused a beacon-report before. The rejection reasons can be found by looking at the bits defined by: - MEASUREMENT_REPORT_MODE_ACCEPT - MEASUREMENT_REPORT_MODE_REJECT_LATE - MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE - MEASUREMENT_REPORT_MODE_REJECT_REFUSED Suggested-by: Ian Clowes Signed-off-by: Nick Hainke --- package/network/services/hostapd/src/src/ap/ubus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 85281f4197..b7b8343892 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -2019,6 +2019,7 @@ void hostapd_ubus_notify_beacon_report( blobmsg_add_macaddr(&b, "bssid", rep->bssid); blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); + blobmsg_add_u16(&b, "rep-mode", rep_mode); ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); } From dbce336539a862c1ef01b69a8b7b137018c3c281 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Sun, 11 Sep 2022 21:53:20 +0200 Subject: [PATCH 11/26] airoha: fix imagebuilder generation by introducing generic target The generic imagebuilder does not have a generic in the name, although this is the default naming scheme. Apply the same fix as for the octeon target. Thanks to @dangowrt for reporting that the same issues applies also for the airoha target. Before the fix: openwrt-imagebuilder-airoha.Linux-x86_64.tar.xz After: openwrt-imagebuilder-airoha-generic.Linux-x86_64.tar.xz Signed-off-by: Nick Hainke --- target/linux/airoha/generic/target.mk | 1 + 1 file changed, 1 insertion(+) create mode 100644 target/linux/airoha/generic/target.mk diff --git a/target/linux/airoha/generic/target.mk b/target/linux/airoha/generic/target.mk new file mode 100644 index 0000000000..f5cb1fb19b --- /dev/null +++ b/target/linux/airoha/generic/target.mk @@ -0,0 +1 @@ +BOARDNAME:=Generic From da6b77215b995eb61edd84b2766930bc963b3331 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 13 Oct 2022 21:49:38 +0200 Subject: [PATCH 12/26] mac80211: fix typo in netifd script Reported-by: Chad Monroe Fixes: 590eaaeed59a ("mac80211: fix issues in HE capabilities") Signed-off-by: Felix Fietkau --- package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 66349f2599..e6f326c2e6 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -436,7 +436,7 @@ mac80211_hostapd_setup_base() { append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" } - mac8q0211_add_he_capabilities \ + mac80211_add_he_capabilities \ he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ From 735f5f18ddbcb5c4e2033f1c08be0113369d2b79 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 14 Oct 2022 13:11:16 +0200 Subject: [PATCH 13/26] iwinfo: update to the latest version 0496c722f1d7 nl80211: fix issues with renamed wiphy and multiple phy per device Signed-off-by: Felix Fietkau --- package/network/utils/iwinfo/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index 9d17e0343a..686b3cef8d 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -11,9 +11,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git -PKG_SOURCE_DATE:=2022-09-22 -PKG_SOURCE_VERSION:=4a43b0d40ba50a21de1d47e7bf0f759be9cf646a -PKG_MIRROR_HASH:=4df2c5ac8cb60e4df06a4ef9a87c3a5196f0a8739ee39e6a2587c15527612250 +PKG_SOURCE_DATE:=2022-10-14 +PKG_SOURCE_VERSION:=0496c722f1d798789d9280d9e357f87b920349eb +PKG_MIRROR_HASH:=6dcbb79b3ebcad3f013a162ee1b18535a05afe9be9bf578cf62d9cf0b210f9df PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=GPL-2.0 From 0a4a0c71937b3251fb9cfc0ccb16b3c41092050b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Sep 2022 13:54:58 +0200 Subject: [PATCH 14/26] libubox: update to the latest version ea56013409d5 jshn.sh: add json_add_fields function for adding multiple fields at once Signed-off-by: Felix Fietkau --- package/libs/libubox/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/libs/libubox/Makefile b/package/libs/libubox/Makefile index 9ad4c30595..e19a97cbba 100644 --- a/package/libs/libubox/Makefile +++ b/package/libs/libubox/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libubox.git -PKG_MIRROR_HASH:=cf48d00ed0ea74d53f2043eb9f9dc52834c0b214f258201cf22dfff7dd6c6e40 -PKG_SOURCE_DATE:=2022-05-15 -PKG_SOURCE_VERSION:=d2223ef9da7172a84d1508733dc58840e1381e3c +PKG_MIRROR_HASH:=400bef38b8c0f382e4e595a50bb52dfbdb8da820eb80f3447b9bd7be3f5499a5 +PKG_SOURCE_DATE:=2022-09-27 +PKG_SOURCE_VERSION:=ea56013409d5823001b47a9bba6f74055a6d76a5 PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) CMAKE_INSTALL:=1 From 7f9d3a00d8d41f2bf9fe35b30cd689b9992e7ff9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Sep 2022 19:19:51 +0200 Subject: [PATCH 15/26] base-files: add helper functions for adding wlan device entries to board.json These will be used to give WLAN PHYs a specific name based on path specified in board.json. The platform board.d script can assign a specific order based on available slots (PCIe slots, WMAC device) and device tree configuration. This helps with maintaining config compatibility in case the device path changes due to kernel upgrades. Signed-off-by: Felix Fietkau --- package/base-files/files/lib/functions/system.sh | 4 ++++ .../files/lib/functions/uci-defaults.sh | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh index 22eb00c515..29de2e5dd6 100644 --- a/package/base-files/files/lib/functions/system.sh +++ b/package/base-files/files/lib/functions/system.sh @@ -283,3 +283,7 @@ macaddr_canonicalize() { printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null } + +dt_is_enabled() { + grep -q okay "/proc/device-tree/$1/status" +} diff --git a/package/base-files/files/lib/functions/uci-defaults.sh b/package/base-files/files/lib/functions/uci-defaults.sh index 86f16b5125..a37e8cf824 100644 --- a/package/base-files/files/lib/functions/uci-defaults.sh +++ b/package/base-files/files/lib/functions/uci-defaults.sh @@ -646,6 +646,21 @@ ucidef_set_ntpserver() { json_select .. } +ucidef_add_wlan() { + local path="$1"; shift + + ucidef_wlan_idx=${ucidef_wlan_idx:-0} + + json_select_object wlan + json_select_object "wl$ucidef_wlan_idx" + json_add_string path "$path" + json_add_fields "$@" + json_select .. + json_select .. + + ucidef_wlan_idx="$((ucidef_wlan_idx + 1))" +} + board_config_update() { json_init [ -f ${CFG} ] && json_load "$(cat ${CFG})" From 6603748e0ca697f484adfc16a0d49d35ed36954d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 23 Sep 2022 14:12:32 +0200 Subject: [PATCH 16/26] mac80211: change default ifname to - This makes it clear, which phy a wlan device belongs to and also helps with telling them apart by including the mode in the ifname. Preparation for automatically renaming PHYs Signed-off-by: Felix Fietkau --- .../files/lib/netifd/wireless/mac80211.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index e6f326c2e6..e05a5b8fee 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -667,13 +667,28 @@ mac80211_iw_interface_add() { return $rc } +mac80211_set_ifname() { + local phy="$1" + local prefix="$2" + eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" +} + mac80211_prepare_vif() { json_select config json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file - [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" - if_idx=$((${if_idx:-0} + 1)) + [ -n "$ifname" ] || { + local prefix; + + case "$mode" in + ap|sta|mesh) prefix=$mode;; + adhoc) prefix=ibss;; + monitor) prefix=mon;; + esac + + mac80211_set_ifname "$phy" "$prefix" + } set_default wds 0 set_default powersave 0 From 4d323303e7e5743f541e3b41dfb2ac1627e8d96d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Sep 2022 20:14:05 +0200 Subject: [PATCH 17/26] mac80211: rename phy according to board.json entries on bringup This allows phy names specified in board.json to be used directly instead of the path option Signed-off-by: Felix Fietkau --- .../files/lib/netifd/wireless/mac80211.sh | 68 ++++++++++++++++++- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index e05a5b8fee..ed2805213e 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -581,15 +581,77 @@ mac80211_generate_mac() { $(( (0x$6 + $id) % 0x100 )) } +get_board_phy_name() ( + local path="$1" + local fallback_phy="" + + __check_phy() { + local val="$1" + local key="$2" + local ref_path="$3" + + json_select "$key" + json_get_values path + json_select .. + + [ "${ref_path%+*}" = "$path" ] && fallback_phy=$key + [ "$ref_path" = "$path" ] || return 0 + + echo "$key" + exit + } + + json_load_file /etc/board.json + json_for_each_item __check_phy wlan "$path" + [ -n "$fallback_phy" ] && echo "${fallback_phy}.${path##*+}" +) + +rename_board_phy_by_path() { + local path="$1" + + local new_phy="$(get_board_phy_name "$path")" + [ -z "$new_phy" -o "$new_phy" = "$phy" ] && return + + iw "$phy" set name "$new_phy" && phy="$new_phy" +} + +rename_board_phy_by_name() ( + local phy="$1" + local suffix="${phy##*.}" + [ "$suffix" = "$phy" ] && suffix= + + json_load_file /etc/board.json + json_select wlan + json_select "${phy%.*}" || return 0 + json_get_values path + + prev_phy="$(iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")" + [ -n "$prev_phy" ] || return 0 + + [ "$prev_phy" = "$phy" ] && return 0 + + iw "$prev_phy" set name "$phy" +) + find_phy() { - [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 + [ -n "$phy" ] && { + rename_board_phy_by_name "$phy" + [ -d /sys/class/ieee80211/$phy ] && return 0 + } [ -n "$path" ] && { phy="$(iwinfo nl80211 phyname "path=$path")" - [ -n "$phy" ] && return 0 + [ -n "$phy" ] && { + rename_board_phy_by_path "$path" + return 0 + } } [ -n "$macaddr" ] && { for phy in $(ls /sys/class/ieee80211 2>/dev/null); do - grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0 + grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { + path="$(iwinfo nl80211 path "$phy")" + rename_board_phy_by_path "$path" + return 0 + } done } return 1 From db9c4a066aadef7be304ab4bdb44f31eac5fbc0d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Oct 2022 13:26:32 +0200 Subject: [PATCH 18/26] mac80211: fix detecting highest radio* config section index Deal with gaps by iterating over existing sections instead of counting Signed-off-by: Felix Fietkau --- .../kernel/mac80211/files/lib/wifi/mac80211.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 6aa46b0c74..c46498b0d4 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -135,14 +135,19 @@ get_band_defaults() { done } +check_devidx() { + case "$1" in + radio[0-9]*) + local idx="${1#radio}" + [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) + ;; + esac +} + detect_mac80211() { devidx=0 config_load wireless - while :; do - config_get type "radio$devidx" type - [ -n "$type" ] || break - devidx=$(($devidx + 1)) - done + config_foreach check_devidx wifi-device for _dev in /sys/class/ieee80211/*; do [ -e "$_dev" ] || continue From 50a03decdf32624c19cbcdd8713eda5e0011eaac Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 23 Sep 2022 14:39:59 +0200 Subject: [PATCH 19/26] mac80211: change the default config for a renamed wiphy use option phy to reference the device instead of path/macaddr Signed-off-by: Felix Fietkau --- .../mac80211/files/lib/wifi/mac80211.sh | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index c46498b0d4..7166f3a12c 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -165,31 +165,38 @@ detect_mac80211() { get_band_defaults "$dev" - path="$(iwinfo nl80211 path "$dev")" - if [ -n "$path" ]; then - dev_id="set wireless.radio${devidx}.path='$path'" - else - dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)" - fi + name="radio${devidx}" + devidx=$(($devidx + 1)) + case "$dev" in + phy*) + path="$(iwinfo nl80211 path "$dev")" + if [ -n "$path" ]; then + dev_id="set wireless.${name}.path='$path'" + else + dev_id="set wireless.${name}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)" + fi + ;; + *) + dev_id="set wireless.${name}.phy='$dev'" + ;; + esac uci -q batch <<-EOF - set wireless.radio${devidx}=wifi-device - set wireless.radio${devidx}.type=mac80211 + set wireless.${name}=wifi-device + set wireless.${name}.type=mac80211 ${dev_id} - set wireless.radio${devidx}.channel=${channel} - set wireless.radio${devidx}.band=${mode_band} - set wireless.radio${devidx}.htmode=$htmode - set wireless.radio${devidx}.disabled=1 + set wireless.${name}.channel=${channel} + set wireless.${name}.band=${mode_band} + set wireless.${name}.htmode=$htmode + set wireless.${name}.disabled=1 - set wireless.default_radio${devidx}=wifi-iface - set wireless.default_radio${devidx}.device=radio${devidx} - set wireless.default_radio${devidx}.network=lan - set wireless.default_radio${devidx}.mode=ap - set wireless.default_radio${devidx}.ssid=OpenWrt - set wireless.default_radio${devidx}.encryption=none + set wireless.default_${name}=wifi-iface + set wireless.default_${name}.device=${name} + set wireless.default_${name}.network=lan + set wireless.default_${name}.mode=ap + set wireless.default_${name}.ssid=OpenWrt + set wireless.default_${name}.encryption=none EOF uci -q commit wireless - - devidx=$(($devidx + 1)) done } From a7ca1b2314cee3cd1d9ee28c7852b6d73258e229 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 1 Oct 2022 16:04:03 +0200 Subject: [PATCH 20/26] mac80211: use board.json provided phy names in generated default config The phy will be automatically renamed on setup Signed-off-by: Felix Fietkau --- .../mac80211/files/lib/wifi/mac80211.sh | 113 ++++++++++-------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 7166f3a12c..3ecd932228 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -2,60 +2,48 @@ append DRIVERS "mac80211" -lookup_phy() { - [ -n "$phy" ] && { - [ -d /sys/class/ieee80211/$phy ] && return - } - - local devpath - config_get devpath "$device" path - [ -n "$devpath" ] && { - phy="$(iwinfo nl80211 phyname "path=$devpath")" - [ -n "$phy" ] && return - } - - local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')" - [ -n "$macaddr" ] && { - for _phy in /sys/class/ieee80211/*; do - [ -e "$_phy" ] || continue - - [ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue - phy="${_phy##*/}" - return - done - } - phy= - return -} - -find_mac80211_phy() { +check_mac80211_device() { local device="$1" + local path="$2" + local macaddr="$3" + [ -n "$found" ] && return 0 + + phy_path= config_get phy "$device" phy - lookup_phy - [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || { - echo "PHY for wifi device $1 not found" - return 1 + json_select wlan + [ -n "$phy" ] && case "$phy" in + phy*) + [ -d /sys/class/ieee80211/$phy ] && \ + phy_path="$(iwinfo nl80211 path "$dev")" + ;; + *) + if json_is_a "$phy" object; then + json_select "$phy" + json_get_var phy_path path + json_select .. + elif json_is_a "${phy%.*}" object; then + json_select "${phy%.*}" + json_get_var phy_path path + json_select .. + phy_path="$phy_path+${phy##*.}" + fi + ;; + esac + json_select .. + [ -n "$phy_path" ] || config_get phy_path "$device" path + [ -n "$path" -a "$phy_path" = "$path" ] && { + found=1 + return 0 } - config_set "$device" phy "$phy" - config_get macaddr "$device" macaddr - [ -z "$macaddr" ] && { - config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)" - } + config_get dev_macaddr "$device" macaddr + + [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 return 0 } -check_mac80211_device() { - config_get phy "$1" phy - [ -z "$phy" ] && { - find_mac80211_phy "$1" >/dev/null || return 0 - config_get phy "$1" phy - } - [ "$phy" = "$dev" ] && found=1 -} - __get_band_defaults() { local phy="$1" @@ -144,20 +132,32 @@ check_devidx() { esac } +check_board_phy() { + local name="$2" + + json_select "$name" + json_get_var phy_path path + json_select .. + + if [ "$path" = "$phy_path" ]; then + board_dev="$name" + elif [ "${path%+*}" = "$phy_path" ]; then + fallback_board_dev="$name.${path#*+}" + fi +} + detect_mac80211() { devidx=0 config_load wireless config_foreach check_devidx wifi-device + json_load_file /etc/board.json + for _dev in /sys/class/ieee80211/*; do [ -e "$_dev" ] || continue dev="${_dev##*/}" - found=0 - config_foreach check_mac80211_device wifi-device - [ "$found" -gt 0 ] && continue - mode_band="" channel="" htmode="" @@ -165,15 +165,26 @@ detect_mac80211() { get_band_defaults "$dev" + path="$(iwinfo nl80211 path "$dev")" + macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" + board_dev= + fallback_board_dev= + json_for_each_item check_board_phy wlan + [ -n "$board_dev" ] || board_dev="$fallback_board_dev" + [ -n "$board_dev" ] && dev="$board_dev" + + found= + config_foreach check_mac80211_device wifi-device "$path" "$macaddr" + [ -n "$found" ] && continue + name="radio${devidx}" devidx=$(($devidx + 1)) case "$dev" in phy*) - path="$(iwinfo nl80211 path "$dev")" if [ -n "$path" ]; then dev_id="set wireless.${name}.path='$path'" else - dev_id="set wireless.${name}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)" + dev_id="set wireless.${name}.macaddr='$macaddr'" fi ;; *) From 34054e4c0635c5820cdab69f3d3979075b4e8795 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Sep 2022 19:32:50 +0200 Subject: [PATCH 21/26] mediatek: fill wlan device entries in board.json on mt7622 Signed-off-by: Felix Fietkau --- .../mt7622/base-files/etc/board.d/02_network | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network index e76792164d..7781fcd435 100644 --- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network @@ -34,6 +34,17 @@ mediatek_setup_interfaces() esac } +DEV_PATH_WMAC=platform/18000000.wmac +DEV_PATH_PCIE0=1a143000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0 +DEV_PATH_PCIE1=1a145000.pcie/pci0001:00/0001:00:01.0/0001:01:00.0 + +mediatek_setup_wlan() +{ + dt_is_enabled wmac@18000000 && ucidef_add_wlan $DEV_PATH_WMAC + dt_is_enabled pcie@1a143000 && ucidef_add_wlan $DEV_PATH_PCIE0 + dt_is_enabled pcie@1a145000 && ucidef_add_wlan $DEV_PATH_PCIE1 +} + mediatek_setup_macs() { local board="$1" @@ -60,6 +71,7 @@ board_config_update board=$(board_name) mediatek_setup_interfaces $board mediatek_setup_macs $board +mediatek_setup_wlan $board board_config_flush exit 0 From d3cd09d1c6b0ef86738793d9c599c3aecfc6c7d3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 11 Oct 2022 14:20:40 +0200 Subject: [PATCH 22/26] kernel: add missing lockdep config symbols for 5.15 Signed-off-by: Felix Fietkau --- target/linux/generic/config-5.15 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 2950ea1a6b..686475c4ca 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -3182,6 +3182,11 @@ CONFIG_LLC=y CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_LOCKD is not set +CONFIG_LOCKDEP_BITS=15 +CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12 +CONFIG_LOCKDEP_CHAINS_BITS=16 +CONFIG_LOCKDEP_STACK_TRACE_BITS=19 +CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14 CONFIG_LOCKDEP_SUPPORT=y CONFIG_LOCKD_V4=y # CONFIG_LOCKUP_DETECTOR is not set From 9995dd254374aa627257ab3218512877a9ae33de Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 11 Oct 2022 14:20:04 +0200 Subject: [PATCH 23/26] kernel: remove target specific CONFIG_IKCONFIG lines Use generic configuration for this feature Signed-off-by: Felix Fietkau --- target/linux/archs38/config-5.10 | 2 -- target/linux/bcm27xx/bcm2708/config-5.15 | 2 -- target/linux/bcm27xx/bcm2709/config-5.15 | 2 -- target/linux/bcm27xx/bcm2710/config-5.15 | 2 -- target/linux/bcm27xx/bcm2711/config-5.15 | 2 -- target/linux/layerscape/armv7/config-5.10 | 2 -- target/linux/layerscape/armv8_64b/config-5.10 | 2 -- target/linux/mediatek/filogic/config-5.15 | 2 -- target/linux/mediatek/mt7622/config-5.15 | 2 -- target/linux/omap/config-5.10 | 2 -- target/linux/omap/config-5.15 | 2 -- target/linux/zynq/config-5.10 | 2 -- 12 files changed, 24 deletions(-) diff --git a/target/linux/archs38/config-5.10 b/target/linux/archs38/config-5.10 index 1460d35535..442f741328 100644 --- a/target/linux/archs38/config-5.10 +++ b/target/linux/archs38/config-5.10 @@ -152,8 +152,6 @@ CONFIG_IIO_ST_SENSORS_I2C=y CONFIG_IIO_ST_SENSORS_SPI=y CONFIG_IIO_TRIGGER=y CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IRQCHIP=y CONFIG_IRQ_DOMAIN=y diff --git a/target/linux/bcm27xx/bcm2708/config-5.15 b/target/linux/bcm27xx/bcm2708/config-5.15 index 9f2c6f266f..6fde682ffd 100644 --- a/target/linux/bcm27xx/bcm2708/config-5.15 +++ b/target/linux/bcm27xx/bcm2708/config-5.15 @@ -199,8 +199,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set diff --git a/target/linux/bcm27xx/bcm2709/config-5.15 b/target/linux/bcm27xx/bcm2709/config-5.15 index 7a01f594e2..63e3b3bdbb 100644 --- a/target/linux/bcm27xx/bcm2709/config-5.15 +++ b/target/linux/bcm27xx/bcm2709/config-5.15 @@ -252,8 +252,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set diff --git a/target/linux/bcm27xx/bcm2710/config-5.15 b/target/linux/bcm27xx/bcm2710/config-5.15 index 308a9246cc..2f1b82484e 100644 --- a/target/linux/bcm27xx/bcm2710/config-5.15 +++ b/target/linux/bcm27xx/bcm2710/config-5.15 @@ -249,8 +249,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y diff --git a/target/linux/bcm27xx/bcm2711/config-5.15 b/target/linux/bcm27xx/bcm2711/config-5.15 index e9e50ea26d..61ced4508a 100644 --- a/target/linux/bcm27xx/bcm2711/config-5.15 +++ b/target/linux/bcm27xx/bcm2711/config-5.15 @@ -256,8 +256,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y diff --git a/target/linux/layerscape/armv7/config-5.10 b/target/linux/layerscape/armv7/config-5.10 index 52bd032905..8c0e5b6ffe 100644 --- a/target/linux/layerscape/armv7/config-5.10 +++ b/target/linux/layerscape/armv7/config-5.10 @@ -292,8 +292,6 @@ CONFIG_I2C_SLAVE_EEPROM=y CONFIG_I2C_XILINX=y CONFIG_ICPLUS_PHY=y CONFIG_ICS932S401=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_IMX2_WDT=y # CONFIG_IMX7ULP_WDT is not set # CONFIG_IMX8MM_THERMAL is not set diff --git a/target/linux/layerscape/armv8_64b/config-5.10 b/target/linux/layerscape/armv8_64b/config-5.10 index c480b71006..0d4afa9809 100644 --- a/target/linux/layerscape/armv8_64b/config-5.10 +++ b/target/linux/layerscape/armv8_64b/config-5.10 @@ -381,8 +381,6 @@ CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_RK3X=y CONFIG_I2C_SLAVE=y # CONFIG_I2C_SLAVE_TESTUNIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_IMX2_WDT=y CONFIG_INET_DIAG=y diff --git a/target/linux/mediatek/filogic/config-5.15 b/target/linux/mediatek/filogic/config-5.15 index 558894e5e5..ae82f8a24d 100644 --- a/target/linux/mediatek/filogic/config-5.15 +++ b/target/linux/mediatek/filogic/config-5.15 @@ -184,8 +184,6 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MT65XX=y CONFIG_ICPLUS_PHY=y CONFIG_IIO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" CONFIG_IO_URING=y diff --git a/target/linux/mediatek/mt7622/config-5.15 b/target/linux/mediatek/mt7622/config-5.15 index c21ec45e90..a47f95c142 100644 --- a/target/linux/mediatek/mt7622/config-5.15 +++ b/target/linux/mediatek/mt7622/config-5.15 @@ -212,8 +212,6 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MT65XX=y CONFIG_ICPLUS_PHY=y CONFIG_IIO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" CONFIG_IO_URING=y diff --git a/target/linux/omap/config-5.10 b/target/linux/omap/config-5.10 index 4aadb401a7..c3178b4702 100644 --- a/target/linux/omap/config-5.10 +++ b/target/linux/omap/config-5.10 @@ -273,8 +273,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_OMAP=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y diff --git a/target/linux/omap/config-5.15 b/target/linux/omap/config-5.15 index c35a20acda..7b0dd7c908 100644 --- a/target/linux/omap/config-5.15 +++ b/target/linux/omap/config-5.15 @@ -277,8 +277,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_OMAP=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y diff --git a/target/linux/zynq/config-5.10 b/target/linux/zynq/config-5.10 index 228b710ec1..767ee677f6 100644 --- a/target/linux/zynq/config-5.10 +++ b/target/linux/zynq/config-5.10 @@ -246,8 +246,6 @@ CONFIG_IIO_BUFFER=y CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGER=y CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_INPUT=y CONFIG_INPUT_EVDEV=y From ef8b935c95c344358946e2c1d27189caa6289d89 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 12 Oct 2022 12:39:41 +0200 Subject: [PATCH 24/26] mediatek: clean up mt7622 kernel config Remove a few unused options to reduce kernel size Signed-off-by: Felix Fietkau --- target/linux/mediatek/mt7622/config-5.15 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/target/linux/mediatek/mt7622/config-5.15 b/target/linux/mediatek/mt7622/config-5.15 index a47f95c142..de44c1360c 100644 --- a/target/linux/mediatek/mt7622/config-5.15 +++ b/target/linux/mediatek/mt7622/config-5.15 @@ -73,7 +73,7 @@ CONFIG_COMMON_CLK_MT7622_ETHSYS=y CONFIG_COMMON_CLK_MT7622_HIFSYS=y # CONFIG_COMMON_CLK_MT7986 is not set # CONFIG_COMMON_CLK_MT8173 is not set -CONFIG_COMMON_CLK_MT8183=y +# CONFIG_COMMON_CLK_MT8183 is not set # CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set # CONFIG_COMMON_CLK_MT8183_CAMSYS is not set # CONFIG_COMMON_CLK_MT8183_IMGSYS is not set @@ -85,7 +85,7 @@ CONFIG_COMMON_CLK_MT8183=y # CONFIG_COMMON_CLK_MT8183_MMSYS is not set # CONFIG_COMMON_CLK_MT8183_VDECSYS is not set # CONFIG_COMMON_CLK_MT8183_VENCSYS is not set -CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516 is not set # CONFIG_COMMON_CLK_MT8516_AUDSYS is not set CONFIG_COMPAT=y CONFIG_COMPAT_32BIT_TIME=y @@ -146,7 +146,6 @@ CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_MISC=y CONFIG_DIMLIB=y CONFIG_DMADEVICES=y -CONFIG_DMATEST=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y CONFIG_DMA_ENGINE_RAID=y @@ -211,10 +210,8 @@ CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MT65XX=y CONFIG_ICPLUS_PHY=y -CONFIG_IIO=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" -CONFIG_IO_URING=y CONFIG_IRQCHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y From 85ae64bb273420533ac790b5a609fb4888b30fc2 Mon Sep 17 00:00:00 2001 From: Bruno Umuarama Date: Fri, 14 Oct 2022 00:37:39 +0000 Subject: [PATCH 25/26] mediatek: mt7623: fix thermal zone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raising the temperatures for passive and active trips. @VA1DER proposed at issue 9396 to remove passive trip. This commit relates to his suggestion. Without this patch. the CPU will be throttled all the way down to 98MHz if the temperature rises even a degree above the trip point, and it was further discovered that if the internal temperature of the device is above the first trip point temperature when it boots then it will start in a throttled state and even $ echo disabled > /sys/class/thermal/thermal_zone0/mode will have no effect. The patch increases the passive trip point and active cooling map. The throttling temperature will then be at 77°C and 82°C, which is still a low enough temperature for ARM devices to not be in the real danger zone, and gives some operational headroom. Signed-off-by: Bruno Umuarama --- .../193-dts-mt7623-thermal_zone_fix.patch | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch diff --git a/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch b/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch new file mode 100644 index 0000000000..1cfb53d620 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch @@ -0,0 +1,48 @@ +From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001 +From: Bruno Umuarama +Date: Thu, 13 Oct 2022 21:18:21 +0000 +Subject: [PATCH] mediatek: mt7623: fix thermal zone +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Raising the temperatures for passive and active trips. @VA1DER +proposed at issue 9396 to remove passive trip. This commit relates to +his suggestion. + +Without this patch. the CPU will be throttled all the way down to 98MHz +if the temperature rises even a degree above the trip point, and it was +further discovered that if the internal temperature of the device is +above the first trip point temperature when it boots then it will start +in a throttled state and even +$ echo disabled > /sys/class/thermal/thermal_zone0/mode +will have no effect. + +The patch increases the passive trip point and active cooling map. The +throttling temperature will then be at 77°C and 82°C, which is still a +low enough temperature for ARM devices to not be in the real danger +zone, and gives some operational headroom. + +Signed-off-by: Bruno Umuarama +--- + arch/arm/boot/dts/mt7623.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -160,13 +160,13 @@ + + trips { + cpu_passive: cpu-passive { +- temperature = <57000>; ++ temperature = <77000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu-active { +- temperature = <67000>; ++ temperature = <82000>; + hysteresis = <2000>; + type = "active"; + }; From fcff86be06da37e1b0839d12efd4a5afc40e8973 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 14 Oct 2022 15:10:52 +0200 Subject: [PATCH 26/26] generic: 5.15: backport qca8k fixup patches for Big-Endian systems Backport qca8k fixup patches for inband mgmt on Big-Endian systems. This is needed for ath79 and mpc85xx targets that are Big-Endian and use qca8k based switch. Signed-off-by: Christian Marangi --- ...x-inband-mgmt-for-big-endian-systems.patch | 163 ++++++++++++++++++ ...x-ethtool-autocast-mib-for-big-endia.patch | 88 ++++++++++ 2 files changed, 251 insertions(+) create mode 100644 target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch create mode 100644 target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch diff --git a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch new file mode 100644 index 0000000000..e706874a6a --- /dev/null +++ b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch @@ -0,0 +1,163 @@ +From a2550d3ce53c68f54042bc5e468c4d07491ffe0e Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 12 Oct 2022 19:18:36 +0200 +Subject: [PATCH 1/2] net: dsa: qca8k: fix inband mgmt for big-endian systems + +The header and the data of the skb for the inband mgmt requires +to be in little-endian. This is problematic for big-endian system +as the mgmt header is written in the cpu byte order. + +Fix this by converting each value for the mgmt header and data to +little-endian, and convert to cpu byte order the mgmt header and +data sent by the switch. + +Fixes: 5950c7c0a68c ("net: dsa: qca8k: add support for mgmt read/write in Ethernet packet") +Tested-by: Pawel Dembicki +Tested-by: Lech Perczak +Signed-off-by: Christian Marangi +Reviewed-by: Lech Perczak +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 63 ++++++++++++++++++++++++-------- + include/linux/dsa/tag_qca.h | 6 +-- + 2 files changed, 50 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c +index 5669c92c93f7..644338ca0510 100644 +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) + struct qca8k_mgmt_eth_data *mgmt_eth_data; + struct qca8k_priv *priv = ds->priv; + struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u32 command; + u8 len, cmd; ++ int i; + + mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); + mgmt_eth_data = &priv->mgmt_eth_data; + +- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); +- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); ++ command = get_unaligned_le32(&mgmt_ethhdr->command); ++ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); ++ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); + + /* Make sure the seq match the requested packet */ +- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) ++ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq) + mgmt_eth_data->ack = true; + + if (cmd == MDIO_READ) { +- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; ++ u32 *val = mgmt_eth_data->data; ++ ++ *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data); + + /* Get the rest of the 12 byte of data. + * The read/write function will extract the requested data. + */ +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(mgmt_eth_data->data + 1, skb->data, +- QCA_HDR_MGMT_DATA2_LEN); ++ if (len > QCA_HDR_MGMT_DATA1_LEN) { ++ __le32 *data2 = (__le32 *)skb->data; ++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, ++ len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ val++; ++ ++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { ++ *val = get_unaligned_le32(data2); ++ val++; ++ data2++; ++ } ++ } + } + + complete(&mgmt_eth_data->rw_done); +@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + struct qca_mgmt_ethhdr *mgmt_ethhdr; + unsigned int real_len; + struct sk_buff *skb; +- u32 *data2; ++ __le32 *data2; ++ u32 command; + u16 hdr; ++ int i; + + skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); + if (!skb) +@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); + hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); + +- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, ++ command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); ++ command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); ++ command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); ++ command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, + QCA_HDR_MGMT_CHECK_CODE_VAL); + ++ put_unaligned_le32(command, &mgmt_ethhdr->command); ++ + if (cmd == MDIO_WRITE) +- mgmt_ethhdr->mdio_data = *val; ++ put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data); + + mgmt_ethhdr->hdr = htons(hdr); + + data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); +- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) { ++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, ++ len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ val++; ++ ++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { ++ put_unaligned_le32(*val, data2); ++ data2++; ++ val++; ++ } ++ } + + return skb; + } +@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) + { + struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u32 seq; + ++ seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); + mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; +- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); ++ put_unaligned_le32(seq, &mgmt_ethhdr->seq); + } + + static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h +index 50be7cbd93a5..0e176da1e43f 100644 +--- a/include/linux/dsa/tag_qca.h ++++ b/include/linux/dsa/tag_qca.h +@@ -61,9 +61,9 @@ struct sk_buff; + + /* Special struct emulating a Ethernet header */ + struct qca_mgmt_ethhdr { +- u32 command; /* command bit 31:0 */ +- u32 seq; /* seq 63:32 */ +- u32 mdio_data; /* first 4byte mdio */ ++ __le32 command; /* command bit 31:0 */ ++ __le32 seq; /* seq 63:32 */ ++ __le32 mdio_data; /* first 4byte mdio */ + __be16 hdr; /* qca hdr */ + } __packed; + +-- +2.37.2 + diff --git a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch new file mode 100644 index 0000000000..93c0bb85b5 --- /dev/null +++ b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch @@ -0,0 +1,88 @@ +From 0d4636f7d72df3179b20a2d32b647881917a5e2a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 12 Oct 2022 19:18:37 +0200 +Subject: [PATCH 2/2] net: dsa: qca8k: fix ethtool autocast mib for big-endian + systems + +The switch sends autocast mib in little-endian. This is problematic for +big-endian system as the values needs to be converted. + +Fix this by converting each mib value to cpu byte order. + +Fixes: 5c957c7ca78c ("net: dsa: qca8k: add support for mib autocast in Ethernet packet") +Tested-by: Pawel Dembicki +Tested-by: Lech Perczak +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 20 ++++++++------------ + include/linux/dsa/tag_qca.h | 2 +- + 2 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c +index 644338ca0510..c5c3b4e92f28 100644 +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1518,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk + struct qca8k_priv *priv = ds->priv; + const struct qca8k_mib_desc *mib; + struct mib_ethhdr *mib_ethhdr; +- int i, mib_len, offset = 0; +- u64 *data; ++ __le32 *data2; + u8 port; ++ int i; + + mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); + mib_eth_data = &priv->mib_eth_data; +@@ -1532,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk + if (port != mib_eth_data->req_port) + goto exit; + +- data = mib_eth_data->data; ++ data2 = (__le32 *)skb->data; + + for (i = 0; i < priv->info->mib_count; i++) { + mib = &ar8327_mib[i]; + + /* First 3 mib are present in the skb head */ + if (i < 3) { +- data[i] = mib_ethhdr->data[i]; ++ mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i); + continue; + } + +- mib_len = sizeof(uint32_t); +- + /* Some mib are 64 bit wide */ + if (mib->size == 2) +- mib_len = sizeof(uint64_t); +- +- /* Copy the mib value from packet to the */ +- memcpy(data + i, skb->data + offset, mib_len); ++ mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2); ++ else ++ mib_eth_data->data[i] = get_unaligned_le32(data2); + +- /* Set the offset for the next mib */ +- offset += mib_len; ++ data2 += mib->size; + } + + exit: +diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h +index 0e176da1e43f..b1b5720d89a5 100644 +--- a/include/linux/dsa/tag_qca.h ++++ b/include/linux/dsa/tag_qca.h +@@ -73,7 +73,7 @@ enum mdio_cmd { + }; + + struct mib_ethhdr { +- u32 data[3]; /* first 3 mib counter */ ++ __le32 data[3]; /* first 3 mib counter */ + __be16 hdr; /* qca hdr */ + } __packed; + +-- +2.37.2 +