[<prev] [next>] [day] [month] [year] [list]
Message-Id: <819ff534-1351-46a1-98a3-069a6cdcc0f2n@aisle.com>
Date: Mon, 25 Aug 2025 11:03:32 -0700 (PDT)
From: Disclosure <disclosure@...le.com>
To: Disclosure <disclosure@...le.com>
Cc: netdev@...r.kernel.org, edumazet@...gle.com, <security@...nel.org>
Subject: [PATCH net] netrom: validate header lengths in nr_rx_frame() using
pskb_may_pull()
>From 0c03a83d9853b1d7f88a7399a8d08b35696f78a5 Mon Sep 17 00:00:00 2001
From: Stanislav Fort <disclosure@...le.com>
Date: Mon, 25 Aug 2025 19:51:12 +0200
Subject: [PATCH] [PATCH net] netrom: validate header lengths in
nr_rx_frame()
using pskb_may_pull()
NET/ROM nr_rx_frame() dereferences the 5-byte transport header
unconditionally. nr_route_frame() currently accepts frames as short as
NR_NETWORK_LEN (15 bytes), which can lead to small out-of-bounds reads
on short frames.
Fix by using pskb_may_pull() in nr_rx_frame() to ensure the full
NET/ROM network + transport header is present before accessing it, and
guard the extra fields used by NR_CONNREQ (window, user address, and the
optional BPQ timeout extension) with additional pskb_may_pull() checks.
This aligns with recent fixes using pskb_may_pull() to validate header
availability.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Stanislav Fort <disclosure@...le.com>
Cc: stable@...r.kernel.org
Signed-off-by: Stanislav Fort <disclosure@...le.com>
---
net/netrom/af_netrom.c | 12 +++++++++++-
net/netrom/nr_route.c | 2 +-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 3331669d8e33..1fbaa161288a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -885,6 +885,10 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device
*dev)
* skb->data points to the netrom frame start
*/
+ /* Ensure NET/ROM network + transport header are present */
+ if (!pskb_may_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN))
+ return 0;
+
src = (ax25_address *)(skb->data + 0);
dest = (ax25_address *)(skb->data + 7);
@@ -961,6 +965,12 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device
*dev)
return 0;
}
+ /* Ensure NR_CONNREQ fields (window + user address) are present */
+ if (!pskb_may_pull(skb, 21 + AX25_ADDR_LEN)) {
+ nr_transmit_refusal(skb, 0);
+ return 0;
+ }
+
sk = nr_find_listener(dest);
user = (ax25_address *)(skb->data + 21);
@@ -1005,7 +1015,7 @@ int nr_rx_frame(struct sk_buff *skb, struct
net_device *dev)
nr_make->window = window;
/* L4 timeout negotiation */
- if (skb->len == 37) {
+ if (skb->len == 37 && pskb_may_pull(skb, 37)) {
timeout = skb->data[36] * 256 + skb->data[35];
if (timeout * HZ < nr_make->t1)
nr_make->t1 = timeout * HZ;
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index b94cb2ffbaf8..b4b0ee546799 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -758,7 +758,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
* Reject malformed packets early. Check that it contains at least 2
* addresses and 1 byte more for Time-To-Live
*/
- if (skb->len < 2 * sizeof(ax25_address) + 1)
+ if (skb->len < NR_NETWORK_LEN)
return 0;
nr_src = (ax25_address *)(skb->data + 0);
--
2.39.3 (Apple Git-146)
Content of type "text/html" skipped
Powered by blists - more mailing lists