diff options
author | Johannes Berg <johannes.berg@intel.com> | 2017-06-14 09:28:11 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2017-06-14 13:52:44 +0200 |
commit | 68dd02d19c811ca8ea60220a9d73e13b4bdad73a (patch) | |
tree | fc5f16101d532733fd8e4d34ea064313580fa163 /net/wireless | |
parent | wireless: wext: use struct iwreq earlier in the call chain (diff) | |
download | linux-68dd02d19c811ca8ea60220a9d73e13b4bdad73a.tar.xz linux-68dd02d19c811ca8ea60220a9d73e13b4bdad73a.zip |
dev_ioctl: copy only the smaller struct iwreq for wext
Unfortunately, struct iwreq isn't a proper subset of struct ifreq,
but is still handled by the same code path. Robert reported that
then applications may (randomly) fault if the struct iwreq they
pass happens to land within 8 bytes of the end of a mapping (the
struct is only 32 bytes, vs. struct ifreq's 40 bytes).
To fix this, pull out the code handling wireless extension ioctls
and copy only the smaller structure in this case.
This bug goes back a long time, I tracked that it was introduced
into mainline in 2.1.15, over 20 years ago!
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=195869
Reported-by: Robert O'Callahan <robert@ocallahan.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/wext-core.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 12949c8d3e5f..6cdb054484d6 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -1035,18 +1035,18 @@ static int ioctl_standard_call(struct net_device * dev, } -int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, +int wext_handle_ioctl(struct net *net, struct iwreq *iwr, unsigned int cmd, void __user *arg) { struct iw_request_info info = { .cmd = cmd, .flags = 0 }; int ret; - ret = wext_ioctl_dispatch(net, (void *)ifr, cmd, &info, + ret = wext_ioctl_dispatch(net, iwr, cmd, &info, ioctl_standard_call, ioctl_private_call); if (ret >= 0 && IW_IS_GET(cmd) && - copy_to_user(arg, ifr, sizeof(struct iwreq))) + copy_to_user(arg, iwr, sizeof(struct iwreq))) return -EFAULT; return ret; |