* [PATCH] 6lowpan: do not compress headers that are not fully present
@ 2026-09-10 20:31 Farhad Alemi
2026-09-10 22:48 ` bluez.test.bot
2026-09-11 1:16 ` [PATCH] " Eric Dumazet
0 siblings, 2 replies; 3+ messages in thread
From: Farhad Alemi @ 2026-09-10 20:31 UTC (permalink / raw)
To: Alexander Aring, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Farhad Alemi, falemi, Simon Horman, Marcel Holtmann,
Luiz Augusto von Dentz, linux-bluetooth, linux-wpan, netdev,
linux-kernel
lowpan_header_compress() pays for the IPHC header it pushes by first
calling skb_pull(skb, sizeof(struct ipv6hdr)), but that pull is a no-op
when skb->len is shorter than an IPv6 header, so the unpaid skb_push() can
drive skb->data below skb->head and into skb_under_panic().
lowpan_nhc_check_compression() has the same missing length check,
committing to the next-header compression path without requiring the
nhc->nexthdrlen transport bytes that nhc->compress() reads and
lowpan_nhc_do_compression() then pulls. Return -EINVAL from
lowpan_header_compress() when pskb_may_pull() cannot produce a full IPv6
header, and return -ENOENT from lowpan_nhc_check_compression() unless the
IPv6 header plus nhc->nexthdrlen bytes are present, so that the nexthdr
falls back to its inline encoding.
Closes: https://lore.kernel.org/all/CA+0ovCjTsygN76s2o=TZqPqW8v2gBhmRnz+q6G-NaB3Cq-YPqQ@mail.gmail.com/
Signed-off-by: Farhad Alemi <farhad.alemi@berkeley.edu>
---
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -1140,6 +1140,10 @@ int lowpan_header_compress(struct sk_buff *skb,
const struct net_device *dev,
if (skb->protocol != htons(ETH_P_IPV6))
return -EINVAL;
+ /* The IPHC header pushed below is paid for by pulling this header. */
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+ return -EINVAL;
+
hdr = ipv6_hdr(skb);
hc_ptr = head + 2;
--- a/net/6lowpan/nhc.c
+++ b/net/6lowpan/nhc.c
@@ -47,7 +47,9 @@ int lowpan_nhc_check_compression(struct sk_buff *skb,
spin_lock_bh(&lowpan_nhc_lock);
nhc = lowpan_nexthdr_nhcs[hdr->nexthdr];
- if (!(nhc && nhc->compress))
+ /* nhc->compress() reads and then pulls nexthdrlen transport bytes. */
+ if (!(nhc && nhc->compress) ||
+ !pskb_may_pull(skb, sizeof(struct ipv6hdr) + nhc->nexthdrlen))
ret = -ENOENT;
spin_unlock_bh(&lowpan_nhc_lock);
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: 6lowpan: do not compress headers that are not fully present
2026-09-10 20:31 [PATCH] 6lowpan: do not compress headers that are not fully present Farhad Alemi
@ 2026-09-10 22:48 ` bluez.test.bot
2026-09-11 1:16 ` [PATCH] " Eric Dumazet
1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-09-10 22:48 UTC (permalink / raw)
To: linux-bluetooth, farhad.alemi
[-- Attachment #1: Type: text/plain, Size: 773 bytes --]
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
error: corrupt patch at line 4
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] 6lowpan: do not compress headers that are not fully present
2026-09-10 20:31 [PATCH] 6lowpan: do not compress headers that are not fully present Farhad Alemi
2026-09-10 22:48 ` bluez.test.bot
@ 2026-09-11 1:16 ` Eric Dumazet
1 sibling, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2026-09-11 1:16 UTC (permalink / raw)
To: Farhad Alemi
Cc: Alexander Aring, David S. Miller, Jakub Kicinski, Paolo Abeni,
falemi, Simon Horman, Marcel Holtmann, Luiz Augusto von Dentz,
linux-bluetooth, linux-wpan, netdev, linux-kernel
On Thu, Sep 10, 2026 at 1:31 PM Farhad Alemi <farhad.alemi@berkeley.edu> wrote:
>
> lowpan_header_compress() pays for the IPHC header it pushes by first
> calling skb_pull(skb, sizeof(struct ipv6hdr)), but that pull is a no-op
> when skb->len is shorter than an IPv6 header, so the unpaid skb_push() can
> drive skb->data below skb->head and into skb_under_panic().
> lowpan_nhc_check_compression() has the same missing length check,
> committing to the next-header compression path without requiring the
> nhc->nexthdrlen transport bytes that nhc->compress() reads and
> lowpan_nhc_do_compression() then pulls. Return -EINVAL from
> lowpan_header_compress() when pskb_may_pull() cannot produce a full IPv6
> header, and return -ENOENT from lowpan_nhc_check_compression() unless the
> IPv6 header plus nhc->nexthdrlen bytes are present, so that the nexthdr
> falls back to its inline encoding.
>
> Closes: https://lore.kernel.org/all/CA+0ovCjTsygN76s2o=TZqPqW8v2gBhmRnz+q6G-NaB3Cq-YPqQ@mail.gmail.com/
> Signed-off-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Notes in a semi random order.
1) You forgot to tag the net tree in your patch.
2) You forgot the Fixes: tag
Please look at Documentation/process/maintainer-netdev.rst for more details.
3) In net/6lowpan/nhc.c, calling pskb_may_pull() inside
lowpan_nhc_check_compression() can reallocate skb->head (via
pskb_expand_head()).
When this happens, the 'hdr' pointer in lowpan_header_compress()
becomes dangling. lowpan_header_compress() continues to dereference
hdr throughout the rest of the function (hdr->nexthdr, hdr->hop_limit,
hdr->saddr, hdr->daddr), leading to a use-after-free.
4) Callers of lowpan_header_compress() do not check its return value.
In net/bluetooth/6lowpan.c (setup_header()) and
net/ieee802154/6lowpan/tx.c (lowpan_header()), the return code of
lowpan_header_compress() is completely ignored. If it returns -EINVAL,
they proceed to transmit the malformed/uncompressed skb anyway.
5) In net/bluetooth/6lowpan.c:setup_header(), there is already an
out-of-bounds read before lowpan_header_compress() is even called:
hdr = ipv6_hdr(skb);
...
memcpy(&ipv6_daddr, &hdr->daddr, sizeof(ipv6_daddr));
If skb->len is less than sizeof(struct ipv6hdr), reading hdr->daddr
is already out of bounds. The driver's transmit path (bt_xmit /
setup_header) needs to validate skb length / pskb_may_pull before
touching the IPv6 header, and must check the return value of
lowpan_header_compress().
Thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-11 1:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 20:31 [PATCH] 6lowpan: do not compress headers that are not fully present Farhad Alemi
2026-09-10 22:48 ` bluez.test.bot
2026-09-11 1:16 ` [PATCH] " Eric Dumazet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox