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

cfg80211: fix error path in cfg80211_wext_siwscan

If there's an invalid channel or SSID, the code leaks
the scan request. Always free the scan request, unless
it was successfully given to the driver.

Reported-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Johannes Berg and committed by
John W. Linville
65486c8b befabac2

+9 -4
+9 -4
net/wireless/scan.c
··· 601 601 struct cfg80211_registered_device *rdev; 602 602 struct wiphy *wiphy; 603 603 struct iw_scan_req *wreq = NULL; 604 - struct cfg80211_scan_request *creq; 604 + struct cfg80211_scan_request *creq = NULL; 605 605 int i, err, n_channels = 0; 606 606 enum ieee80211_band band; 607 607 ··· 694 694 /* translate "Scan for SSID" request */ 695 695 if (wreq) { 696 696 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 697 - if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) 698 - return -EINVAL; 697 + if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) { 698 + err = -EINVAL; 699 + goto out; 700 + } 699 701 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); 700 702 creq->ssids[0].ssid_len = wreq->essid_len; 701 703 } ··· 709 707 err = rdev->ops->scan(wiphy, dev, creq); 710 708 if (err) { 711 709 rdev->scan_req = NULL; 712 - kfree(creq); 710 + /* creq will be freed below */ 713 711 } else { 714 712 nl80211_send_scan_start(rdev, dev); 713 + /* creq now owned by driver */ 714 + creq = NULL; 715 715 dev_hold(dev); 716 716 } 717 717 out: 718 + kfree(creq); 718 719 cfg80211_unlock_rdev(rdev); 719 720 return err; 720 721 }