Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: cfg80211/mac80211: validate radio frequency range for monitor mode

In multi-radio devices, it is possible to have an MLD AP and a monitor
interface active at the same time. In such cases, monitor mode may not
be able to specify a fixed channel and could end up capturing frames
from all radios, including those outside the intended frequency bands.

This patch adds frequency validation for monitor mode. Received frames
are now only processed if their frequency fall within the allowed ranges
of the radios specified by the interface's radio_mask.

This prevents monitor mode from capturing frames outside the supported radio.

Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Link: https://patch.msgid.link/700b8284e845d96654eb98431f8eeb5a81503862.1758647858.git.ryder.lee@mediatek.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Ryder Lee and committed by
Johannes Berg
a392cde8 428ea708

+66 -3
+14
include/net/cfg80211.h
··· 1015 1015 cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1, 1016 1016 const struct cfg80211_chan_def *chandef2); 1017 1017 1018 + 1018 1019 /** 1019 1020 * nl80211_chan_width_to_mhz - get the channel width in MHz 1020 1021 * @chan_width: the channel width from &enum nl80211_chan_width ··· 6882 6881 6883 6882 return ieee80211_frequency_to_channel(chan->center_freq) % 16 == 5; 6884 6883 } 6884 + 6885 + /** 6886 + * ieee80211_radio_freq_range_valid - Check if the radio supports the 6887 + * specified frequency range 6888 + * 6889 + * @radio: wiphy radio 6890 + * @freq: the frequency (in KHz) to be queried 6891 + * @width: the bandwidth (in KHz) to be queried 6892 + * 6893 + * Return: whether or not the given frequency range is valid for the given radio 6894 + */ 6895 + bool ieee80211_radio_freq_range_valid(const struct wiphy_radio *radio, 6896 + u32 freq, u32 width); 6885 6897 6886 6898 /** 6887 6899 * cfg80211_radio_chandef_valid - Check if the radio supports the chandef
+49
net/mac80211/rx.c
··· 763 763 return skb; 764 764 } 765 765 766 + static bool 767 + ieee80211_validate_monitor_radio(struct ieee80211_sub_if_data *sdata, 768 + struct ieee80211_local *local, 769 + struct ieee80211_rx_status *status) 770 + { 771 + struct wiphy *wiphy = local->hw.wiphy; 772 + int i, freq, bw; 773 + 774 + if (!wiphy->n_radio) 775 + return true; 776 + 777 + switch (status->bw) { 778 + case RATE_INFO_BW_20: 779 + bw = 20000; 780 + break; 781 + case RATE_INFO_BW_40: 782 + bw = 40000; 783 + break; 784 + case RATE_INFO_BW_80: 785 + bw = 80000; 786 + break; 787 + case RATE_INFO_BW_160: 788 + bw = 160000; 789 + break; 790 + case RATE_INFO_BW_320: 791 + bw = 320000; 792 + break; 793 + default: 794 + return false; 795 + } 796 + 797 + freq = MHZ_TO_KHZ(status->freq); 798 + 799 + for (i = 0; i < wiphy->n_radio; i++) { 800 + if (!(sdata->wdev.radio_mask & BIT(i))) 801 + continue; 802 + 803 + if (!ieee80211_radio_freq_range_valid(&wiphy->radio[i], freq, bw)) 804 + continue; 805 + 806 + return true; 807 + } 808 + return false; 809 + } 810 + 766 811 /* 767 812 * This function copies a received frame to all monitor interfaces and 768 813 * returns a cleaned-up SKB that no longer includes the FCS nor the ··· 898 853 chandef = &sdata->vif.bss_conf.chanreq.oper; 899 854 if (chandef->chan && 900 855 chandef->chan->center_freq != status->freq) 856 + continue; 857 + 858 + if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) && 859 + !ieee80211_validate_monitor_radio(sdata, local, status)) 901 860 continue; 902 861 903 862 if (!prev_sdata) {
+3 -3
net/wireless/util.c
··· 2942 2942 } 2943 2943 EXPORT_SYMBOL(cfg80211_get_iftype_ext_capa); 2944 2944 2945 - static bool 2946 - ieee80211_radio_freq_range_valid(const struct wiphy_radio *radio, 2947 - u32 freq, u32 width) 2945 + bool ieee80211_radio_freq_range_valid(const struct wiphy_radio *radio, 2946 + u32 freq, u32 width) 2948 2947 { 2949 2948 const struct wiphy_radio_freq_range *r; 2950 2949 int i; ··· 2957 2958 2958 2959 return false; 2959 2960 } 2961 + EXPORT_SYMBOL(ieee80211_radio_freq_range_valid); 2960 2962 2961 2963 bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio, 2962 2964 const struct cfg80211_chan_def *chandef)