This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 47a880a29bd net/sixlowpan: Fix HC06 UDP NHC decompression
47a880a29bd is described below
commit 47a880a29bd49fac81099b44816f1083cd72148d
Author: chao an <[email protected]>
AuthorDate: Thu Oct 22 22:40:57 2026 +0800
net/sixlowpan: Fix HC06 UDP NHC decompression
The HC06 decompressor accepted LOWPAN_NHC_UDP even when UDP
support was not enabled. For subsequent fragments,
sixlowpan_input() decompresses headers into g_bitbucket, which is
sized from enabled transport protocols, so reconstructing a UDP header
can overrun that buffer in non-UDP builds.
Keep UDP NHC handling behind CONFIG_NET_UDP, reject compressed next
headers otherwise, and check the inline NHC/checksum bytes before
consuming them.
Signed-off-by: chao an <[email protected]>
---
net/sixlowpan/sixlowpan_hc06.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c
index 7da821d2798..04e3ddacc50 100644
--- a/net/sixlowpan/sixlowpan_hc06.c
+++ b/net/sixlowpan/sixlowpan_hc06.c
@@ -1471,13 +1471,15 @@ int sixlowpan_uncompresshdr_hc06(FAR struct
radio_driver_s *radio,
if ((iphc0 & SIXLOWPAN_IPHC_NH) != 0)
{
- FAR struct udp_hdr_s *udp =
- (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
-
/* The next header is compressed, NHC is following */
+ HC06_CHECK(g_hc06ptr, 1, endofframe);
+
+#ifdef CONFIG_NET_UDP
if ((*g_hc06ptr & SIXLOWPAN_NHC_UDP_MASK) == SIXLOWPAN_NHC_UDP_ID)
{
+ FAR struct udp_hdr_s *udp =
+ (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
uint8_t checksum_compressed;
ipv6->proto = IP_PROTO_UDP;
@@ -1570,6 +1572,7 @@ int sixlowpan_uncompresshdr_hc06(FAR struct
radio_driver_s *radio,
{
/* Has_checksum, default */
+ HC06_CHECK(g_hc06ptr, 2, endofframe);
memcpy(&udp->udpchksum, g_hc06ptr, 2);
g_hc06ptr += 2;
@@ -1582,6 +1585,15 @@ int sixlowpan_uncompresshdr_hc06(FAR struct
radio_driver_s *radio,
g_uncomp_hdrlen += UDP_HDRLEN;
}
+ else
+ {
+ nwarn("WARNING: Unsupported next header compression\n");
+ return -EPROTONOSUPPORT;
+ }
+#else
+ nwarn("WARNING: Next header compression unsupported\n");
+ return -EPROTONOSUPPORT;
+#endif /* CONFIG_NET_UDP */
}
g_frame_hdrlen = g_hc06ptr - fptr;
@@ -1604,14 +1616,17 @@ int sixlowpan_uncompresshdr_hc06(FAR struct
radio_driver_s *radio,
ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00ff;
}
+#ifdef CONFIG_NET_UDP
/* Length field in UDP header */
if (ipv6->proto == IP_PROTO_UDP)
{
FAR struct udp_hdr_s *udp =
(FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
+
memcpy(&udp->udplen, &ipv6->len[0], 2);
}
+#endif /* CONFIG_NET_UDP */
return OK;
}