Commit 14e05beb authored by Jacob Keller's avatar Jacob Keller Committed by Johannes Berg
Browse files

wifi: nl80211: convert cfg80211_scan_request allocation to *_size macros



The cfg80211_scan_request structure is followed by a flexible array member
as well as several other arrays that are then stored into pointers in the
structure. These are allocated currently using a simple sequence of
multiplications.

Replace the calculations with struct_size(), size_add(), and array_size()
helper macros. These macros saturate the calculation at SIZE_MAX rather
than overflowing.

Note that we can't use flex_array_size() instead of array_size() because
the fields are not arrays, but simple pointers.

Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Link: https://lore.kernel.org/r/20230228162827.3876606-3-jacob.e.keller@intel.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 69334861
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -9027,7 +9027,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
	struct nlattr *attr;
	struct wiphy *wiphy;
	int err, tmp, n_ssids = 0, n_channels, i;
	size_t ie_len;
	size_t ie_len, size;
	wiphy = &rdev->wiphy;
@@ -9072,10 +9072,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
	if (ie_len > wiphy->max_scan_ie_len)
		return -EINVAL;
	request = kzalloc(sizeof(*request)
			+ sizeof(*request->ssids) * n_ssids
			+ sizeof(*request->channels) * n_channels
			+ ie_len, GFP_KERNEL);
	size = struct_size(request, channels, n_channels);
	size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
	size = size_add(size, ie_len);
	request = kzalloc(size, GFP_KERNEL);
	if (!request)
		return -ENOMEM;
@@ -9408,7 +9408,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
	struct nlattr *attr;
	int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
	enum nl80211_band band;
	size_t ie_len;
	size_t ie_len, size;
	struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
	s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
@@ -9517,12 +9517,14 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
	     attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
		return ERR_PTR(-EINVAL);
	request = kzalloc(sizeof(*request)
			+ sizeof(*request->ssids) * n_ssids
			+ sizeof(*request->match_sets) * n_match_sets
			+ sizeof(*request->scan_plans) * n_plans
			+ sizeof(*request->channels) * n_channels
			+ ie_len, GFP_KERNEL);
	size = struct_size(request, channels, n_channels);
	size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
	size = size_add(size, array_size(sizeof(*request->match_sets),
					 n_match_sets));
	size = size_add(size, array_size(sizeof(*request->scan_plans),
					 n_plans));
	size = size_add(size, ie_len);
	request = kzalloc(size, GFP_KERNEL);
	if (!request)
		return ERR_PTR(-ENOMEM);