diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8188ad200de5..32cef926f8a4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -10992,4 +10992,5 @@ void cfg80211_incumbent_signal_notify(struct wiphy *wiphy, u32 signal_interference_bitmap, gfp_t gfp); +bool cfg80211_validate_ies(const u8 *ies, size_t ies_len); #endif /* __NET_CFG80211_H */ diff --git a/net/wireless/util.c b/net/wireless/util.c index 24527bf321b2..a685020c8efc 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -3083,3 +3083,19 @@ bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev, return false; } EXPORT_SYMBOL(cfg80211_wdev_channel_allowed); + +bool cfg80211_validate_ies(const u8 *ies, size_t ies_len) +{ + size_t pos = 0; + + while (pos < ies_len) { + if (pos + 2 > ies_len) + return false; + if (pos + 2 + ies[pos + 1] > ies_len) + return false; + pos += 2 + ies[pos + 1]; + } + + return true; +} +EXPORT_SYMBOL(cfg80211_validate_ies); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 573b6b15a446..3e9b071f6d66 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -319,6 +319,8 @@ int cfg80211_wext_siwgenie(struct net_device *dev, return 0; if (ie_len) { + if (!cfg80211_validate_ies(extra, ie_len)) + return -EINVAL; ie = kmemdup(extra, ie_len, GFP_KERNEL); if (!ie) return -ENOMEM;