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

wifi: mac80211: ethtool: always hold wiphy mutex

Drivers should really be able to rely on the wiphy mutex
being held all the time, unless otherwise documented. For
ethtool, that wasn't quite right. Fix and clarify this in
both code and documentation.

Reported-by: syzbot+c12a771b218dcbba32e1@syzkaller.appspotmail.com
Fixes: 0e8185ce1dde ("wifi: mac80211: check wiphy mutex in ops")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+12 -1
+4
include/net/mac80211.h
··· 4067 4067 * This callback must be atomic. 4068 4068 * 4069 4069 * @get_et_sset_count: Ethtool API to get string-set count. 4070 + * Note that the wiphy mutex is not held for this callback since it's 4071 + * expected to return a static value. 4070 4072 * 4071 4073 * @get_et_stats: Ethtool API to get a set of u64 stats. 4072 4074 * 4073 4075 * @get_et_strings: Ethtool API to get a set of strings to describe stats 4074 4076 * and perhaps other supported types of ethtool data-sets. 4077 + * Note that the wiphy mutex is not held for this callback since it's 4078 + * expected to return a static value. 4075 4079 * 4076 4080 * @mgd_prepare_tx: Prepare for transmitting a management frame for association 4077 4081 * before associated. In multi-channel scenarios, a virtual interface is
+8 -1
net/mac80211/ethtool.c
··· 19 19 struct netlink_ext_ack *extack) 20 20 { 21 21 struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy); 22 + int ret; 22 23 23 24 if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) 24 25 return -EINVAL; 25 26 26 - return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending); 27 + wiphy_lock(local->hw.wiphy); 28 + ret = drv_set_ringparam(local, rp->tx_pending, rp->rx_pending); 29 + wiphy_unlock(local->hw.wiphy); 30 + 31 + return ret; 27 32 } 28 33 29 34 static void ieee80211_get_ringparam(struct net_device *dev, ··· 40 35 41 36 memset(rp, 0, sizeof(*rp)); 42 37 38 + wiphy_lock(local->hw.wiphy); 43 39 drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending, 44 40 &rp->rx_pending, &rp->rx_max_pending); 41 + wiphy_unlock(local->hw.wiphy); 45 42 } 46 43 47 44 static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {