]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Oct 2019 13:40:05 +0000 (15:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Oct 2019 13:40:05 +0000 (15:40 +0200)
added patches:
cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch
cfg80211-use-const-more-consistently-in-for_each_element-macros.patch
nl80211-validate-beacon-head.patch

queue-4.4/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch [new file with mode: 0644]
queue-4.4/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch [new file with mode: 0644]
queue-4.4/nl80211-validate-beacon-head.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch b/queue-4.4/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch
new file mode 100644 (file)
index 0000000..9d4b312
--- /dev/null
@@ -0,0 +1,103 @@
+From 0f3b07f027f87a38ebe5c436490095df762819be Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 7 Feb 2019 21:44:41 +0100
+Subject: cfg80211: add and use strongly typed element iteration macros
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 0f3b07f027f87a38ebe5c436490095df762819be upstream.
+
+Rather than always iterating elements from frames with pure
+u8 pointers, add a type "struct element" that encapsulates
+the id/datalen/data format of them.
+
+Then, add the element iteration macros
+ * for_each_element
+ * for_each_element_id
+ * for_each_element_extid
+
+which take, as their first 'argument', such a structure and
+iterate through a given u8 array interpreting it as elements.
+
+While at it and since we'll need it, also add
+ * for_each_subelement
+ * for_each_subelement_id
+ * for_each_subelement_extid
+
+which instead of taking data/length just take an outer element
+and use its data/datalen.
+
+Also add for_each_element_completed() to determine if any of
+the loops above completed, i.e. it was able to parse all of
+the elements successfully and no data remained.
+
+Use for_each_element_id() in cfg80211_find_ie_match() as the
+first user of this.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/ieee80211.h |   53 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -2550,4 +2550,57 @@ static inline bool ieee80211_action_cont
+       return true;
+ }
++struct element {
++      u8 id;
++      u8 datalen;
++      u8 data[];
++};
++
++/* element iteration helpers */
++#define for_each_element(element, _data, _datalen)                    \
++      for (element = (void *)(_data);                                 \
++           (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
++              sizeof(*element) &&                                     \
++           (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
++              sizeof(*element) + element->datalen;                    \
++           element = (void *)(element->data + element->datalen))
++
++#define for_each_element_id(element, _id, data, datalen)              \
++      for_each_element(element, data, datalen)                        \
++              if (element->id == (_id))
++
++#define for_each_element_extid(element, extid, data, datalen)         \
++      for_each_element(element, data, datalen)                        \
++              if (element->id == WLAN_EID_EXTENSION &&                \
++                  element->datalen > 0 &&                             \
++                  element->data[0] == (extid))
++
++#define for_each_subelement(sub, element)                             \
++      for_each_element(sub, (element)->data, (element)->datalen)
++
++#define for_each_subelement_id(sub, id, element)                      \
++      for_each_element_id(sub, id, (element)->data, (element)->datalen)
++
++#define for_each_subelement_extid(sub, extid, element)                        \
++      for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
++
++/**
++ * for_each_element_completed - determine if element parsing consumed all data
++ * @element: element pointer after for_each_element() or friends
++ * @data: same data pointer as passed to for_each_element() or friends
++ * @datalen: same data length as passed to for_each_element() or friends
++ *
++ * This function returns %true if all the data was parsed or considered
++ * while walking the elements. Only use this if your for_each_element()
++ * loop cannot be broken out of, otherwise it always returns %false.
++ *
++ * If some data was malformed, this returns %false since the last parsed
++ * element will not fill the whole remaining data.
++ */
++static inline bool for_each_element_completed(const struct element *element,
++                                            const void *data, size_t datalen)
++{
++      return (u8 *)element == (u8 *)data + datalen;
++}
++
+ #endif /* LINUX_IEEE80211_H */
diff --git a/queue-4.4/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch b/queue-4.4/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch
new file mode 100644 (file)
index 0000000..bed6d1f
--- /dev/null
@@ -0,0 +1,59 @@
+From 7388afe09143210f555bdd6c75035e9acc1fab96 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Mon, 11 Feb 2019 16:29:04 +0200
+Subject: cfg80211: Use const more consistently in for_each_element macros
+
+From: Jouni Malinen <j@w1.fi>
+
+commit 7388afe09143210f555bdd6c75035e9acc1fab96 upstream.
+
+Enforce the first argument to be a correct type of a pointer to struct
+element and avoid unnecessary typecasts from const to non-const pointers
+(the change in validate_ie_attr() is needed to make this part work). In
+addition, avoid signed/unsigned comparison within for_each_element() and
+mark struct element packed just in case.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/ieee80211.h |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -2554,16 +2554,16 @@ struct element {
+       u8 id;
+       u8 datalen;
+       u8 data[];
+-};
++} __packed;
+ /* element iteration helpers */
+-#define for_each_element(element, _data, _datalen)                    \
+-      for (element = (void *)(_data);                                 \
+-           (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
+-              sizeof(*element) &&                                     \
+-           (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
+-              sizeof(*element) + element->datalen;                    \
+-           element = (void *)(element->data + element->datalen))
++#define for_each_element(_elem, _data, _datalen)                      \
++      for (_elem = (const struct element *)(_data);                   \
++           (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >=    \
++              (int)sizeof(*_elem) &&                                  \
++           (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >=    \
++              (int)sizeof(*_elem) + _elem->datalen;                   \
++           _elem = (const struct element *)(_elem->data + _elem->datalen))
+ #define for_each_element_id(element, _id, data, datalen)              \
+       for_each_element(element, data, datalen)                        \
+@@ -2600,7 +2600,7 @@ struct element {
+ static inline bool for_each_element_completed(const struct element *element,
+                                             const void *data, size_t datalen)
+ {
+-      return (u8 *)element == (u8 *)data + datalen;
++      return (const u8 *)element == (const u8 *)data + datalen;
+ }
+ #endif /* LINUX_IEEE80211_H */
diff --git a/queue-4.4/nl80211-validate-beacon-head.patch b/queue-4.4/nl80211-validate-beacon-head.patch
new file mode 100644 (file)
index 0000000..3bb1d0c
--- /dev/null
@@ -0,0 +1,79 @@
+From f88eb7c0d002a67ef31aeb7850b42ff69abc46dc Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 20 Sep 2019 21:54:17 +0200
+Subject: nl80211: validate beacon head
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit f88eb7c0d002a67ef31aeb7850b42ff69abc46dc upstream.
+
+We currently don't validate the beacon head, i.e. the header,
+fixed part and elements that are to go in front of the TIM
+element. This means that the variable elements there can be
+malformed, e.g. have a length exceeding the buffer size, but
+most downstream code from this assumes that this has already
+been checked.
+
+Add the necessary checks to the netlink policy.
+
+Cc: stable@vger.kernel.org
+Fixes: ed1b6cc7f80f ("cfg80211/nl80211: add beacon settings")
+Link: https://lore.kernel.org/r/1569009255-I7ac7fbe9436e9d8733439eab8acbbd35e55c74ef@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/wireless/nl80211.c |   35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -210,6 +210,36 @@ cfg80211_get_dev_from_info(struct net *n
+       return __cfg80211_rdev_from_attrs(netns, info->attrs);
+ }
++static int validate_beacon_head(const struct nlattr *attr)
++{
++      const u8 *data = nla_data(attr);
++      unsigned int len = nla_len(attr);
++      const struct element *elem;
++      const struct ieee80211_mgmt *mgmt = (void *)data;
++      unsigned int fixedlen = offsetof(struct ieee80211_mgmt,
++                                       u.beacon.variable);
++
++      if (len < fixedlen)
++              goto err;
++
++      if (ieee80211_hdrlen(mgmt->frame_control) !=
++          offsetof(struct ieee80211_mgmt, u.beacon))
++              goto err;
++
++      data += fixedlen;
++      len -= fixedlen;
++
++      for_each_element(elem, data, len) {
++              /* nothing */
++      }
++
++      if (for_each_element_completed(elem, data, len))
++              return 0;
++
++err:
++      return -EINVAL;
++}
++
+ /* policy for the attributes */
+ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
+       [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
+@@ -3214,6 +3244,11 @@ static int nl80211_parse_beacon(struct n
+       memset(bcn, 0, sizeof(*bcn));
+       if (attrs[NL80211_ATTR_BEACON_HEAD]) {
++              int ret = validate_beacon_head(attrs[NL80211_ATTR_BEACON_HEAD]);
++
++              if (ret)
++                      return ret;
++
+               bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
+               bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
+               if (!bcn->head_len)
index ec197e7c33305fe12c86aa88d559214eadacc8dd..60f30d871ce3c6449c80888267327806c92b5a91 100644 (file)
@@ -24,3 +24,6 @@ perf-stat-fix-a-segmentation-fault-when-using-repeat.patch
 perf-stat-reset-previous-counts-on-repeat-with-inter.patch
 drm-i915-userptr-acquire-the-page-lock-around-set_pa.patch
 crypto-caam-fix-concurrency-issue-in-givencrypt-descriptor.patch
+cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch
+cfg80211-use-const-more-consistently-in-for_each_element-macros.patch
+nl80211-validate-beacon-head.patch