Commit 9cfc3702 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mac80211-for-davem-2019-10-01' of...

Merge tag 'mac80211-for-davem-2019-10-01' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211



Johannes Berg says:

====================
A small list of fixes this time:
 * two null pointer dereference fixes
 * a fix for preempt-enabled/BHs-enabled (lockdep) splats
   (that correctly pointed out a bug)
 * a fix for multi-BSSID ordering assumptions
 * a fix for the EDMG support, on-stack chandefs need to
   be initialized properly (now that they're bigger)
 * beacon (head) data from userspace should be validated
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6de6d185 d8dec42b
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -487,9 +487,14 @@ static ssize_t ieee80211_if_fmt_aqm(
	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
{
	struct ieee80211_local *local = sdata->local;
	struct txq_info *txqi = to_txq_info(sdata->vif.txq);
	struct txq_info *txqi;
	int len;

	if (!sdata->vif.txq)
		return 0;

	txqi = to_txq_info(sdata->vif.txq);

	spin_lock_bh(&local->fq.lock);
	rcu_read_lock();

@@ -658,7 +663,9 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
	DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
	DEBUGFS_ADD(hw_queues);

	if (sdata->local->ops->wake_tx_queue)
	if (sdata->local->ops->wake_tx_queue &&
	    sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
	    sdata->vif.type != NL80211_IFTYPE_NAN)
		DEBUGFS_ADD(aqm);
}

+8 −5
Original line number Diff line number Diff line
@@ -247,7 +247,8 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
	struct sta_info *sta;
	int i;

	spin_lock_bh(&fq->lock);
	local_bh_disable();
	spin_lock(&fq->lock);

	if (sdata->vif.type == NL80211_IFTYPE_AP)
		ps = &sdata->bss->ps;
@@ -273,9 +274,9 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
						&txqi->flags))
				continue;

			spin_unlock_bh(&fq->lock);
			spin_unlock(&fq->lock);
			drv_wake_tx_queue(local, txqi);
			spin_lock_bh(&fq->lock);
			spin_lock(&fq->lock);
		}
	}

@@ -288,12 +289,14 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
	    (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
		goto out;

	spin_unlock_bh(&fq->lock);
	spin_unlock(&fq->lock);

	drv_wake_tx_queue(local, txqi);
	local_bh_enable();
	return;
out:
	spin_unlock_bh(&fq->lock);
	spin_unlock(&fq->lock);
	local_bh_enable();
}

static void
+41 −3
Original line number Diff line number Diff line
@@ -201,6 +201,38 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
	return __cfg80211_rdev_from_attrs(netns, info->attrs);
}

static int validate_beacon_head(const struct nlattr *attr,
				struct netlink_ext_ack *extack)
{
	const u8 *data = nla_data(attr);
	unsigned int len = nla_len(attr);
	const struct element *elem;
	const struct ieee80211_mgmt *mgmt = (void *)data;
	unsigned int fixedlen = offsetof(struct ieee80211_mgmt,
					 u.beacon.variable);

	if (len < fixedlen)
		goto err;

	if (ieee80211_hdrlen(mgmt->frame_control) !=
	    offsetof(struct ieee80211_mgmt, u.beacon))
		goto err;

	data += fixedlen;
	len -= fixedlen;

	for_each_element(elem, data, len) {
		/* nothing */
	}

	if (for_each_element_completed(elem, data, len))
		return 0;

err:
	NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
	return -EINVAL;
}

static int validate_ie_attr(const struct nlattr *attr,
			    struct netlink_ext_ack *extack)
{
@@ -338,8 +370,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {

	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
	[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
	[NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
				       .len = IEEE80211_MAX_DATA_LEN },
	[NL80211_ATTR_BEACON_HEAD] =
		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
				       IEEE80211_MAX_DATA_LEN),
	[NL80211_ATTR_BEACON_TAIL] =
		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
				       IEEE80211_MAX_DATA_LEN),
@@ -2636,6 +2669,8 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,

	control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);

	memset(chandef, 0, sizeof(*chandef));

	chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
	chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
	chandef->center_freq1 = control_freq;
@@ -3176,7 +3211,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag

	if (rdev->ops->get_channel) {
		int ret;
		struct cfg80211_chan_def chandef;
		struct cfg80211_chan_def chandef = {};

		ret = rdev_get_channel(rdev, wdev, &chandef);
		if (ret == 0) {
@@ -6270,6 +6305,9 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
	if (!rdev->ops->del_mpath)
		return -EOPNOTSUPP;

	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
		return -EOPNOTSUPP;

	return rdev_del_mpath(rdev, dev, dst);
}

+1 −1
Original line number Diff line number Diff line
@@ -2108,7 +2108,7 @@ static void reg_call_notifier(struct wiphy *wiphy,

static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
{
	struct cfg80211_chan_def chandef;
	struct cfg80211_chan_def chandef = {};
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	enum nl80211_iftype iftype;

+6 −1
Original line number Diff line number Diff line
@@ -1723,7 +1723,12 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
		return;
	new_ie_len -= trans_ssid[1];
	mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
	if (!mbssid)
	/*
	 * It's not valid to have the MBSSID element before SSID
	 * ignore if that happens - the code below assumes it is
	 * after (while copying things inbetween).
	 */
	if (!mbssid || mbssid < trans_ssid)
		return;
	new_ie_len -= mbssid[1];
	rcu_read_lock();
Loading