Hello,
While playing with the 6lowpan code, I found a few more bugs. Some a
not very serious as long as interoperability is not required, some other
are more serious and prevent the fragment reassembly to be performed
correctly (after 256 fragments have been sent) or mangle the packet
length field.
I attached a patch to this mail. I hope it applies correctly, as I'm
also modifying the code so that it behaves as described in the RFC (see
my previous mail).
Please let me know what you think, and if you need more details.
Regards,
Tony
From e15083579d7e2b853aa022c4b84edbd091644cbd Mon Sep 17 00:00:00 2001
From: Tony Cheneau <tony.chen...@amnesiak.org>
Date: Tue, 5 Jun 2012 17:26:54 -0400
Subject: [PATCH 1/1] Fixes various u8/u16 storage/usage bugs in the 6lowpan
code: - tag would not be passed down correctly in
lowpan_alloc_new_frame() (pass down a u16 to the
function when it only accepts a u8) -
lowpan_skb_fragmentation() and lowpan_fetch_skb_u16()
would not store/retrieve the data correctly -
lowpan_process_data() and lowpan_alloc_new_frame():
frame length would get corrupted
---
net/ieee802154/6lowpan.c | 26 +++++++++++++++-----------
1 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 245d765..c9428b9 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -313,7 +313,7 @@ static inline int lowpan_fetch_skb_u16(struct sk_buff *skb,
u16 *val)
if (WARN_ON_ONCE(!pskb_may_pull(skb, 2)))
return -EINVAL;
- *val = skb->data[0] | (skb->data[1] << 8);
+ *val = (skb->data[0] << 8) | skb->data[1];
skb_pull(skb, 2);
return 0;
@@ -660,7 +660,7 @@ static void lowpan_fragment_timer_expired(unsigned long
entry_addr)
}
static struct lowpan_fragment *
-lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u8 tag)
+lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag)
{
struct lowpan_fragment *frame;
@@ -671,7 +671,7 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8
len, u8 tag)
INIT_LIST_HEAD(&frame->list);
- frame->length = (iphc0 & 7) | (len << 3);
+ frame->length = len;
frame->tag = tag;
/* allocate buffer for frame assembling */
@@ -729,14 +729,15 @@ lowpan_process_data(struct sk_buff *skb)
case LOWPAN_DISPATCH_FRAGN:
{
struct lowpan_fragment *frame;
- u8 len, offset;
- u16 tag;
+ u8 slen, offset = 0; /* slen is short length */
+ u16 len, tag;
bool found = false;
- if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */
+ if (lowpan_fetch_skb_u8(skb, &slen) || /* 8 LSB of frame length
*/
lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */
goto drop;
+ len = ((iphc0 & 7) << 8) | slen; /* adds the 3 MSB to the 8 LSB to
obtain the 11 bits length */
/*
* check if frame assembling with the same tag is
* already in progress
@@ -751,7 +752,10 @@ lowpan_process_data(struct sk_buff *skb)
/* alloc new frame structure */
if (!found) {
- frame = lowpan_alloc_new_frame(skb, iphc0, len, tag);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s first fragment received for tag %d, begin packet
reassembly", __func__, tag);
+#endif /* DEBUG */
+ frame = lowpan_alloc_new_frame(skb, len, tag);
if (!frame)
goto unlock_and_drop;
}
@@ -1014,10 +1018,10 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
tag = fragment_tag++;
/* first fragment header */
- head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7);
- head[1] = (payload_length >> 3) & 0xff;
- head[2] = tag & 0xff;
- head[3] = tag >> 8;
+ head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7);
+ head[1] = payload_length & 0xff;
+ head[2] = tag >> 8;
+ head[3] = tag & 0xff;
err = lowpan_fragment_xmit(skb, head, header_length, 0, 0);
--
1.7.6.5
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel