[PATCH V2 8/8] nl80211: Migrate from set_tx to key_flag API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Migrate nl80211 driver to key_flag API and add additional sanity checks.

Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx>
---

I redesigned that part quite a bit compared to v1.
A full test run on my systems is - with the other fixes of the series
merged - not triggering any of the additional sanity tests.
(In fact most of them were found by the sanity checks.)

I'm still not sure why we install unicast WEP keys also as default
unicast keys. Based on how I understand how mac80211 handles that it
should be pointless. I just stuck to how we do things prior to the patch
for WEP keys to not break anything. After all other drivers may need it.

 src/drivers/driver_nl80211.c | 48 +++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index d7a67f340..d7a924868 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3055,7 +3055,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 	struct nl_msg *msg;
 	struct nl_msg *key_msg;
 	int ret;
-	int tdls = 0;
+	int skip_set_key = 1;
 	const char *ifname = params->ifname;
 	enum wpa_alg alg = params->alg;
 	const u8 *addr = params->addr;
@@ -3066,6 +3066,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 	const u8 *key = params->key;
 	size_t key_len = params->key_len;
 	int vlan_id = params->vlan_id;
+	enum key_flag key_flag = params->key_flag;
 
 	/* Ignore for P2P Device */
 	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3073,15 +3074,18 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 
 	ifindex = if_nametoindex(ifname);
 	wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
-		   "set_tx=%d seq_len=%lu key_len=%lu",
+		   "set_tx=%d seq_len=%lu key_len=%lu key_flag=0x%x",
 		   __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
-		   (unsigned long) seq_len, (unsigned long) key_len);
+		   (unsigned long) seq_len, (unsigned long) key_len, key_flag);
 #ifdef CONFIG_TDLS
 	if (key_idx == -1) {
 		key_idx = 0;
-		tdls = 1;
 	}
 #endif /* CONFIG_TDLS */
+	if (check_key_flag(key_flag)) {
+		wpa_printf(MSG_DEBUG, "%s: invalid key_flag", __func__);
+		return -EINVAL;
+	}
 
 #ifdef CONFIG_DRIVER_NL80211_QCA
 	if (alg == WPA_ALG_PMK &&
@@ -3096,13 +3100,20 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 	if (alg == WPA_ALG_PMK &&
 	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
 		return nl80211_set_pmk(drv, key, key_len, addr);
+	if (key_flag & KEY_FLAG_PMK)
+		return -EINVAL;
 
 	ret = -ENOBUFS;
 	key_msg = nlmsg_alloc();
 	if (!key_msg)
 		return ret;
 
-	if (alg == WPA_ALG_NONE) {
+	if (alg == WPA_ALG_NONE && key_flag & KEY_FLAG_RX_TX) {
+		wpa_printf(MSG_DEBUG, "%s: invalid key_flag to delete key",
+			   __func__);
+		ret = -EINVAL;
+		goto fail2;
+	} else if (alg == WPA_ALG_NONE) {
 		msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
 		if (!msg)
 			goto fail2;
@@ -3134,14 +3145,29 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 		if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
 			goto fail;
 
-		if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
+		if ((key_flag & KEY_FLAG_GROUP_MASK) == KEY_FLAG_GROUP_RX) {
 			wpa_printf(MSG_DEBUG, "   RSN IBSS RX GTK");
 			if (nla_put_u32(key_msg, NL80211_KEY_TYPE,
 					NL80211_KEYTYPE_GROUP))
 				goto fail;
+		} else if (!(key_flag & KEY_FLAG_PAIRWISE)) {
+			ret = -EINVAL;
+			goto fail;
+		} else if (alg == WPA_ALG_WEP &&
+			   (key_flag & KEY_FLAG_RX_TX) == KEY_FLAG_RX_TX) {
+			wpa_printf(MSG_DEBUG, "   unicast WEP key");
+			skip_set_key = 0;
+		} else {
+			wpa_printf(MSG_DEBUG, "   pairwise key");
 		}
-	} else if (addr && is_broadcast_ether_addr(addr)) {
+	} else if (key_flag & KEY_FLAG_PAIRWISE ||
+		   !(key_flag & KEY_FLAG_GROUP)) {
+		ret = -EINVAL;
+		goto fail;
+	} else {
 		wpa_printf(MSG_DEBUG, "   broadcast key");
+		if (key_flag & KEY_FLAG_DEFAULT)
+			skip_set_key = 0;
 	}
 	if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
 	    nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
@@ -3164,14 +3190,12 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 			   ret, strerror(-ret));
 
 	/*
-	 * If we failed or don't need to set the default TX key (below),
+	 * If we failed or don't need to set the key as default (below),
 	 * we're done here.
 	 */
-	if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
-		return ret;
-	if (is_ap_interface(drv->nlmode) && addr &&
-	    !is_broadcast_ether_addr(addr))
+	if (ret || skip_set_key)
 		return ret;
+	wpa_printf(MSG_DEBUG, "   default key");
 
 	ret = -ENOBUFS;
 	key_msg = nlmsg_alloc();
-- 
2.25.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux