Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108584967
D45619.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D45619.diff
View Options
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -271,8 +271,14 @@
* Otherwise a unicast/pairwise key is specified by the bssid
* (on a station) or mac address (on an ap). They key length
* must include any MIC key data; otherwise it should be no
- * more than IEEE80211_KEYBUF_SIZE.
+ * more than IEEE80211_IOCTL_KEYBUF_SIZE.
*/
+#define IEEE80211_IOCTL_KEYBUF_SIZE (16) /* 128 bit keys */
+#define IEEE80211_IOCTL_MICBUF_SIZE (8+8) /* TX + RX MIC */
+
+#define IEEE80211_IOCTL_KEYDATA_SIZE \
+ (IEEE80211_IOCTL_KEYBUF_SIZE + IEEE80211_IOCTL_MICBUF_SIZE)
+
struct ieee80211req_key {
uint8_t ik_type; /* key/cipher type */
uint8_t ik_pad;
@@ -284,7 +290,7 @@
uint8_t ik_macaddr[IEEE80211_ADDR_LEN];
uint64_t ik_keyrsc; /* key receive sequence counter */
uint64_t ik_keytsc; /* key transmit sequence counter */
- uint8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
+ uint8_t ik_keydata[IEEE80211_IOCTL_KEYDATA_SIZE];
};
/*
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -110,11 +110,18 @@
ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID];
ik.ik_keytsc = wk->wk_keytsc;
memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen);
+
+ /*
+ * Treat the ioctl as a fixed-size key buffer for now
+ * and use the ioctl sizes. This will return truncated
+ * keys the net80211 key is larger, but it won't leak data,
+ * go out of bounds or change the ioctl ABI.
+ */
if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) {
memcpy(ik.ik_keydata+wk->wk_keylen,
- wk->wk_key + IEEE80211_KEYBUF_SIZE,
- IEEE80211_MICBUF_SIZE);
- ik.ik_keylen += IEEE80211_MICBUF_SIZE;
+ wk->wk_key + IEEE80211_IOCTL_KEYBUF_SIZE,
+ IEEE80211_IOCTL_MICBUF_SIZE);
+ ik.ik_keylen += IEEE80211_IOCTL_MICBUF_SIZE;
}
} else {
ik.ik_keyrsc = 0;
@@ -1177,6 +1184,7 @@
struct ieee80211_key *wk;
uint16_t kid;
int error, i;
+ int max_keylen;
if (ireq->i_len != sizeof(ik))
return EINVAL;
@@ -1217,17 +1225,40 @@
wk->wk_keyix = kid;
ni = NULL;
}
+
+ max_keylen = ieee80211_crypto_get_max_keylen(ik.ik_type);
+ if (max_keylen == 0)
+ return EINVAL;
+
error = 0;
ieee80211_key_update_begin(vap);
if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) {
wk->wk_keylen = ik.ik_keylen;
- /* NB: MIC presence is implied by cipher type */
- if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE)
- wk->wk_keylen = IEEE80211_KEYBUF_SIZE;
+
+ /*
+ * Cap the key length at the cipher key length.
+ *
+ * This captures the TKIP case where we're passed in both
+ * a key and the TX/RX MIC; the ioctl API unfortunately
+ * doesn't separate them out. (And in fairness, neither
+ * does the net80211 crypto code.)
+ */
+ if (wk->wk_keylen > max_keylen)
+ wk->wk_keylen = max_keylen;
+
for (i = 0; i < IEEE80211_TID_SIZE; i++)
wk->wk_keyrsc[i] = ik.ik_keyrsc;
wk->wk_keytsc = 0; /* new key, reset */
memset(wk->wk_key, 0, sizeof(wk->wk_key));
+ /*
+ * Copy the key and any tx/rx MIC that is present.
+ *
+ * For TKIP w/ MIC the ik_keylen being passed in
+ * includes tx/rx MIC and this memcpy() copies everything
+ * including the tx/rx MIC blob that may be at the
+ * end of the key. However, wk->wk_keylen needs to be
+ * the actual key length.
+ */
memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen);
IEEE80211_ADDR_COPY(wk->wk_macaddr,
ni != NULL ? ni->ni_macaddr : ik.ik_macaddr);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 27, 3:46 PM (5 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16200262
Default Alt Text
D45619.diff (3 KB)
Attached To
Mode
D45619: net80211: separate out the net80211 ioctl key size from the kernel definition
Attached
Detach File
Event Timeline
Log In to Comment