DragonFlyBSD Kernel Audit
DF-0286 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netproto/802_11/wlan/ieee80211_mesh.c b/sys/netproto/802_11/wlan/ieee80211_mesh.c
--- a/sys/netproto/802_11/wlan/ieee80211_mesh.c
+++ b/sys/netproto/802_11/wlan/ieee80211_mesh.c
@@ -2550,11 +2550,17 @@
 	const struct ieee80211_frame *wh,
 	const uint8_t *frm, const uint8_t *efrm)
 {
-	const struct ieee80211_meshlmetric_ie *ie =
-	    (const struct ieee80211_meshlmetric_ie *)
-	    (frm+2); /* action + code */
+	const struct ieee80211_meshlmetric_ie *ie;
 	struct ieee80211_meshlmetric_ie lm_rep;
 
+	/* ieee80211_parse_action() only guarantees sizeof(struct
+	 * ieee80211_action) (2 bytes: category + action).  Require the full
+	 * Link Metric IE body before reading it, otherwise lm_flags /
+	 * lm_metric read up to ~6 bytes past the valid frame body. */
+	if (efrm - frm < 2 + sizeof(struct ieee80211_meshlmetric_ie))
+		return 0;
+	ie = (const struct ieee80211_meshlmetric_ie *)(frm + 2);
+
 	if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
 		lm_rep.lm_flags = 0;
 		lm_rep.lm_metric = mesh_airtime_calc(ni);