diff options
author | Dan Williams <dan.j.williams@intel.com> | 2018-01-29 20:03:15 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-01-30 15:54:32 -0500 |
commit | 259d8c1e984318497c84eef547bbb6b1d9f4eb05 (patch) | |
tree | 9fc57a04ca95579ebbf6dbaf06b6bab792cb1395 | |
parent | 56c30ba7b348b90484969054d561f711ba196507 (diff) |
nl80211: Sanitize array index in parse_txq_params
Wireless drivers rely on parse_txq_params to validate that txq_params->ac
is less than NL80211_NUM_ACS by the time the low-level driver's ->conf_tx()
handler is called. Use a new helper, array_index_nospec(), to sanitize
txq_params->ac with respect to speculation. I.e. ensure that any
speculation into ->conf_tx() handlers is done with a value of
txq_params->ac that is within the bounds of [0, NL80211_NUM_ACS).
Reported-by: Christian Lamparter <chunkeey@gmail.com>
Reported-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-arch@vger.kernel.org
Cc: kernel-hardening@lists.openwall.com
Cc: gregkh@linuxfoundation.org
Cc: linux-wireless@vger.kernel.org
Cc: torvalds@linux-foundation.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: alan@linux.intel.com
Link: https://lkml.kernel.org/r/151727419584.33451.7700736761686184303.stgit@dwillia2-desk3.amr.corp.intel.com
-rw-r--r-- | net/wireless/nl80211.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 542a4fc0a8d7..4bbcfc1e2d43 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/nl80211.h> | 16 | #include <linux/nl80211.h> |
17 | #include <linux/rtnetlink.h> | 17 | #include <linux/rtnetlink.h> |
18 | #include <linux/netlink.h> | 18 | #include <linux/netlink.h> |
19 | #include <linux/nospec.h> | ||
19 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
20 | #include <net/net_namespace.h> | 21 | #include <net/net_namespace.h> |
21 | #include <net/genetlink.h> | 22 | #include <net/genetlink.h> |
@@ -2056,20 +2057,22 @@ static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { | |||
2056 | static int parse_txq_params(struct nlattr *tb[], | 2057 | static int parse_txq_params(struct nlattr *tb[], |
2057 | struct ieee80211_txq_params *txq_params) | 2058 | struct ieee80211_txq_params *txq_params) |
2058 | { | 2059 | { |
2060 | u8 ac; | ||
2061 | |||
2059 | if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] || | 2062 | if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] || |
2060 | !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || | 2063 | !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || |
2061 | !tb[NL80211_TXQ_ATTR_AIFS]) | 2064 | !tb[NL80211_TXQ_ATTR_AIFS]) |
2062 | return -EINVAL; | 2065 | return -EINVAL; |
2063 | 2066 | ||
2064 | txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]); | 2067 | ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]); |
2065 | txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); | 2068 | txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); |
2066 | txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); | 2069 | txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); |
2067 | txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); | 2070 | txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); |
2068 | txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); | 2071 | txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); |
2069 | 2072 | ||
2070 | if (txq_params->ac >= NL80211_NUM_ACS) | 2073 | if (ac >= NL80211_NUM_ACS) |
2071 | return -EINVAL; | 2074 | return -EINVAL; |
2072 | 2075 | txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS); | |
2073 | return 0; | 2076 | return 0; |
2074 | } | 2077 | } |
2075 | 2078 | ||