Commit 065ddfef authored by Johannes Berg's avatar Johannes Berg Committed by Kleber Sacilotto de Souza

cfg80211: prevent speculation on cfg80211_classify8021d() return

It's possible that the caller of cfg80211_classify8021d() uses the
value to index an array, like mac80211 in ieee80211_downgrade_queue().
Prevent speculation on the return value.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>

CVE-2017-5753

(backported from commit 1fc9b725)
[juergh: Adjusted context.]
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 76e60d5c
......@@ -13,6 +13,7 @@
#include <net/dsfield.h>
#include <linux/if_vlan.h>
#include <linux/mpls.h>
#include <linux/nospec.h>
#include "core.h"
#include "rdev-ops.h"
......@@ -749,20 +750,25 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
{
unsigned int dscp;
unsigned char vlan_priority;
unsigned int ret;
/* skb->priority values from 256->263 are magic values to
* directly indicate a specific 802.1d priority. This is used
* to allow 802.1d priority to be passed directly in from VLAN
* tags, etc.
*/
if (skb->priority >= 256 && skb->priority <= 263)
return skb->priority - 256;
if (skb->priority >= 256 && skb->priority <= 263) {
ret = skb->priority - 256;
goto out;
}
if (skb_vlan_tag_present(skb)) {
vlan_priority = (skb_vlan_tag_get(skb) & VLAN_PRIO_MASK)
>> VLAN_PRIO_SHIFT;
if (vlan_priority > 0)
return vlan_priority;
if (vlan_priority > 0) {
ret = vlan_priority;
goto out;
}
}
switch (skb->protocol) {
......@@ -781,8 +787,9 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
if (!mpls)
return 0;
return (ntohl(mpls->entry) & MPLS_LS_TC_MASK)
ret = (ntohl(mpls->entry) & MPLS_LS_TC_MASK)
>> MPLS_LS_TC_SHIFT;
goto out;
}
case htons(ETH_P_80221):
/* 802.21 is always network control traffic */
......@@ -795,18 +802,24 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
unsigned int i, tmp_dscp = dscp >> 2;
for (i = 0; i < qos_map->num_des; i++) {
if (tmp_dscp == qos_map->dscp_exception[i].dscp)
return qos_map->dscp_exception[i].up;
if (tmp_dscp == qos_map->dscp_exception[i].dscp) {
ret = qos_map->dscp_exception[i].up;
goto out;
}
}
for (i = 0; i < 8; i++) {
if (tmp_dscp >= qos_map->up[i].low &&
tmp_dscp <= qos_map->up[i].high)
return i;
tmp_dscp <= qos_map->up[i].high) {
ret = i;
goto out;
}
}
}
return dscp >> 5;
ret = dscp >> 5;
out:
return array_index_nospec(ret, IEEE80211_NUM_TIDS);
}
EXPORT_SYMBOL(cfg80211_classify8021d);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment