summaryrefslogtreecommitdiff
path: root/patches/collateral-evolutions/network/09-cfg80211-wext-padding
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2013-03-30 00:53:58 +0100
committerJohannes Berg <johannes@sipsolutions.net>2013-03-30 01:06:36 +0100
commit44706a520f6527c67e7f8b741812f11464babda2 (patch)
treeceba8de9f18d05fea9bb4d337391ed79a2bc7cf4 /patches/collateral-evolutions/network/09-cfg80211-wext-padding
parent5bf870f42dc0cf3e31522e05119c0a8f993a280e (diff)
split patches
This splits all patches into per-file patches. I've added the little tool I wrote as well (but it's hard to use). Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'patches/collateral-evolutions/network/09-cfg80211-wext-padding')
-rw-r--r--patches/collateral-evolutions/network/09-cfg80211-wext-padding/INFO30
-rw-r--r--patches/collateral-evolutions/network/09-cfg80211-wext-padding/include_net_cfg80211.h12
-rw-r--r--patches/collateral-evolutions/network/09-cfg80211-wext-padding/net_wireless_core.c20
3 files changed, 62 insertions, 0 deletions
diff --git a/patches/collateral-evolutions/network/09-cfg80211-wext-padding/INFO b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/INFO
new file mode 100644
index 00000000..3d0044da
--- /dev/null
+++ b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/INFO
@@ -0,0 +1,30 @@
+This is a tricky one.
+
+Consider a kernel that has this code in net/wireless/wext-core.c:
+
+#ifdef CONFIG_CFG80211_WEXT
+ if (dev->ieee80211_ptr && dev->ieee80211_ptr->wiphy)
+ handlers = dev->ieee80211_ptr->wiphy->wext;
+#endif
+#ifdef CONFIG_WIRELESS_EXT
+ if (dev->wireless_handlers)
+ handlers = dev->wireless_handlers;
+#endif
+
+If a kernel is compiled without CONFIG_WIRELESS_EXT then
+compat-drivers can't do wireless extensions against it.
+However, if the kernel is compiled with CONFIG_CFG80211_WEXT
+then it will try to get the wext handlers from struct wiphy.
+
+Now, struct wiphy in the base kernel and struct wiphy in
+compat-drivers don't match, so the kernel crashes!!
+
+To fix this, add lots of padding to compat-drivers's
+struct wiphy so that the "wext" pointer is guaranteed
+to be NULL.
+
+Make sure the padding is larger than the struct so we
+don't ever run into this again because the wext pointer
+moved due to struct enlargements.
+
+
diff --git a/patches/collateral-evolutions/network/09-cfg80211-wext-padding/include_net_cfg80211.h b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/include_net_cfg80211.h
new file mode 100644
index 00000000..0661f90d
--- /dev/null
+++ b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/include_net_cfg80211.h
@@ -0,0 +1,12 @@
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -2561,6 +2561,9 @@
+ struct wiphy {
+ /* assign these fields before you register the wiphy */
+
++#define WIPHY_COMPAT_PAD_SIZE 2048
++ u8 padding[WIPHY_COMPAT_PAD_SIZE];
++
+ /* permanent MAC address(es) */
+ u8 perm_addr[ETH_ALEN];
+ u8 addr_mask[ETH_ALEN];
diff --git a/patches/collateral-evolutions/network/09-cfg80211-wext-padding/net_wireless_core.c b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/net_wireless_core.c
new file mode 100644
index 00000000..064e1571
--- /dev/null
+++ b/patches/collateral-evolutions/network/09-cfg80211-wext-padding/net_wireless_core.c
@@ -0,0 +1,20 @@
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -316,6 +316,17 @@
+ struct cfg80211_registered_device *rdev;
+ int alloc_size;
+
++ /*
++ * Make sure the padding is >= the rest of the struct so that we
++ * always keep it large enough to pad out the entire original
++ * kernel's struct. We really only need to make sure it's larger
++ * than the kernel compat is compiled against, but since it'll
++ * only increase in size make sure it's larger than the current
++ * version of it. Subtract since it's included.
++ */
++ BUILD_BUG_ON(WIPHY_COMPAT_PAD_SIZE <
++ sizeof(struct wiphy) - WIPHY_COMPAT_PAD_SIZE);
++
+ WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
+ WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
+ WARN_ON(ops->connect && !ops->disconnect);