| From 5122565188bae59d507d90a9a9fd2fd6107f4439 Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Thu, 21 Jan 2021 17:16:22 +0100 |
| Subject: wext: fix NULL-ptr-dereference with cfg80211's lack of commit() |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 5122565188bae59d507d90a9a9fd2fd6107f4439 upstream. |
| |
| Since cfg80211 doesn't implement commit, we never really cared about |
| that code there (and it's configured out w/o CONFIG_WIRELESS_EXT). |
| After all, since it has no commit, it shouldn't return -EIWCOMMIT to |
| indicate commit is needed. |
| |
| However, EIWCOMMIT is actually an alias for EINPROGRESS, which _can_ |
| happen if e.g. we try to change the frequency but we're already in |
| the process of connecting to some network, and drivers could return |
| that value (or even cfg80211 itself might). |
| |
| This then causes us to crash because dev->wireless_handlers is NULL |
| but we try to check dev->wireless_handlers->standard[0]. |
| |
| Fix this by also checking dev->wireless_handlers. Also simplify the |
| code a little bit. |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: syzbot+444248c79e117bc99f46@syzkaller.appspotmail.com |
| Reported-by: syzbot+8b2a88a09653d4084179@syzkaller.appspotmail.com |
| Link: https://lore.kernel.org/r/20210121171621.2076e4a37d5a.I5d9c72220fe7bb133fb718751da0180a57ecba4e@changeid |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/wireless/wext-core.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| --- a/net/wireless/wext-core.c |
| +++ b/net/wireless/wext-core.c |
| @@ -895,8 +895,9 @@ out: |
| int call_commit_handler(struct net_device *dev) |
| { |
| #ifdef CONFIG_WIRELESS_EXT |
| - if ((netif_running(dev)) && |
| - (dev->wireless_handlers->standard[0] != NULL)) |
| + if (netif_running(dev) && |
| + dev->wireless_handlers && |
| + dev->wireless_handlers->standard[0]) |
| /* Call the commit handler on the driver */ |
| return dev->wireless_handlers->standard[0](dev, NULL, |
| NULL, NULL); |