linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Amir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
To: johannes@sipsolutions.net
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	Amir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
Subject: [PATCH] mac80211: mesh: Fix missing bounds checks in prepare_for_gate()
Date: Sat, 22 Aug 2026 20:21:17 +0330	[thread overview]
Message-ID: <20260822165117.34396-1-a.jahangirzad@gmail.com> (raw)

When moving or copying frames to a gate mpath, prepare_for_gate()
processes incoming packets by reading the MAC header and modifying
the packet to add Address Extension (AE) fields if necessary.

However, the function lacked proper bounds checking on the incoming
skb, exposing the code to potential crashes and out-of-bounds reads.
Specifically, the function calculates `hdrlen` from the frame control
field and then directly accesses the mesh header at `skb->data + hdrlen`
without checking if `skb->len` is actually large enough to hold this
data. If a truncated packet is processed, this can result in an
out-of-bounds read.

Furthermore, when the packet does not have the Address Extension flags,
the function calls `skb_push(skb, 2 * ETH_ALEN)`. It performs this push
without verifying if the `skb` actually has enough headroom available.
If a packet exhausts the available headroom, this will trigger a BUG()
in `skb_push` and cause a kernel crash.

This patch fixes these issues by validating `skb->len` before reading
any headers and checking `skb_headroom()` before modifying the packet.
`prepare_for_gate()` is modified to return an `int` (-EINVAL on
failure), and its caller is updated to gracefully drop malformed
packets instead of queueing them.

Signed-off-by: Amir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
---
 net/mac80211/mesh_pathtbl.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 03171cf00855..b344f305a85f 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -131,22 +131,32 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
 	spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
 }
 
-static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
-			     struct mesh_path *gate_mpath)
+static int prepare_for_gate(struct sk_buff *skb, char *dst_addr,
+			    struct mesh_path *gate_mpath)
 {
 	struct ieee80211_hdr *hdr;
 	struct ieee80211s_hdr *mshdr;
 	int mesh_hdrlen, hdrlen;
 	char *next_hop;
 
+	if (skb->len < sizeof(struct ieee80211_hdr))
+		return -EINVAL;
+
 	hdr = (struct ieee80211_hdr *) skb->data;
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+	if (skb->len < hdrlen + 6)
+		return -EINVAL;
+
 	mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
 
 	if (!(mshdr->flags & MESH_FLAGS_AE)) {
 		/* size of the fixed part of the mesh header */
 		mesh_hdrlen = 6;
 
+		if (skb_headroom(skb) < 2 * ETH_ALEN)
+			return -EINVAL;
+
 		/* make room for the two extended addresses */
 		skb_push(skb, 2 * ETH_ALEN);
 		memmove(skb->data, hdr, hdrlen + mesh_hdrlen);
@@ -169,6 +179,7 @@ static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
 	rcu_read_unlock();
 	memcpy(hdr->addr2, gate_mpath->sdata->vif.addr, ETH_ALEN);
 	memcpy(hdr->addr3, dst_addr, ETH_ALEN);
+	return 0;
 }
 
 /**
@@ -218,8 +229,10 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
 		if (WARN_ON(!skb))
 			break;
 
-		prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
-		skb_queue_tail(&gate_mpath->frame_queue, skb);
+		if (prepare_for_gate(skb, gate_mpath->dst, gate_mpath) == 0)
+			skb_queue_tail(&gate_mpath->frame_queue, skb);
+		else
+			kfree_skb(skb);
 
 		if (copy)
 			continue;
-- 
2.55.0


                 reply	other threads:[~2026-08-22 16:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260822165117.34396-1-a.jahangirzad@gmail.com \
    --to=a.jahangirzad@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).