Loading net/ieee802154/6lowpan.c +38 −32 Original line number Diff line number Diff line Loading @@ -291,25 +291,26 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) *hc06_ptr += 2; } static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) { u8 ret; if (unlikely(!pskb_may_pull(skb, 1))) return -EINVAL; ret = skb->data[0]; *val = skb->data[0]; skb_pull(skb, 1); return ret; return 0; } static u16 lowpan_fetch_skb_u16(struct sk_buff *skb) static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) { u16 ret; BUG_ON(!pskb_may_pull(skb, 2)); if (unlikely(!pskb_may_pull(skb, 2))) return -EINVAL; ret = skb->data[0] | (skb->data[1] << 8); *val = skb->data[0] | (skb->data[1] << 8); skb_pull(skb, 2); return ret; return 0; } static int Loading @@ -318,7 +319,8 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) struct udphdr *uh = udp_hdr(skb); u8 tmp; tmp = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &tmp)) goto err; if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { pr_debug("(%s): UDP header uncompression\n", __func__); Loading Loading @@ -710,7 +712,9 @@ lowpan_process_data(struct sk_buff *skb) /* at least two bytes will be used for the encoding */ if (skb->len < 2) goto drop; iphc0 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc0)) goto drop; /* fragments assembling */ switch (iphc0 & LOWPAN_DISPATCH_MASK) { Loading @@ -722,8 +726,9 @@ lowpan_process_data(struct sk_buff *skb) u16 tag; bool found = false; len = lowpan_fetch_skb_u8(skb); /* frame length */ tag = lowpan_fetch_skb_u16(skb); if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ goto drop; /* * check if frame assembling with the same tag is Loading @@ -747,7 +752,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) goto unlock_and_drop; offset = lowpan_fetch_skb_u8(skb); /* fetch offset */ if (lowpan_fetch_skb_u8(skb, &offset)) /* fetch offset */ goto unlock_and_drop; /* if payload fits buffer, copy it */ if (likely((offset * 8 + skb->len) <= frame->length)) Loading @@ -769,7 +775,10 @@ lowpan_process_data(struct sk_buff *skb) dev_kfree_skb(skb); skb = frame->skb; kfree(frame); iphc0 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc0)) goto unlock_and_drop; break; } spin_unlock(&flist_lock); Loading @@ -780,7 +789,8 @@ lowpan_process_data(struct sk_buff *skb) break; } iphc1 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc1)) goto drop; _saddr = mac_cb(skb)->sa.hwaddr; _daddr = mac_cb(skb)->da.hwaddr; Loading @@ -791,9 +801,8 @@ lowpan_process_data(struct sk_buff *skb) if (iphc1 & LOWPAN_IPHC_CID) { pr_debug("(%s): CID flag is set, increase header with one\n", __func__); if (!skb->len) if (lowpan_fetch_skb_u8(skb, &num_context)) goto drop; num_context = lowpan_fetch_skb_u8(skb); } hdr.version = 6; Loading @@ -805,9 +814,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */ case 0: /* 00b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); memcpy(&hdr.flow_lbl, &skb->data[0], 3); skb_pull(skb, 3); hdr.priority = ((tmp >> 2) & 0x0f); Loading @@ -819,9 +828,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP (1 byte), Flow Label is elided */ case 1: /* 10b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); hdr.priority = ((tmp >> 2) & 0x0f); hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); hdr.flow_lbl[1] = 0; Loading @@ -832,9 +841,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */ case 2: /* 01b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); skb_pull(skb, 2); Loading @@ -853,9 +862,9 @@ lowpan_process_data(struct sk_buff *skb) /* Next Header */ if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) goto drop; hdr.nexthdr = lowpan_fetch_skb_u8(skb); pr_debug("(%s): NH flag is set, next header is carried " "inline: %02x\n", __func__, hdr.nexthdr); } Loading @@ -864,9 +873,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I) hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03]; else { if (!skb->len) if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit))) goto drop; hdr.hop_limit = lowpan_fetch_skb_u8(skb); } /* Extract SAM to the tmp variable */ Loading Loading @@ -894,10 +902,8 @@ lowpan_process_data(struct sk_buff *skb) pr_debug("(%s): destination address non-context-based" " multicast compression\n", __func__); if (0 < tmp && tmp < 3) { if (!skb->len) if (lowpan_fetch_skb_u8(skb, &prefix[1])) goto drop; else prefix[1] = lowpan_fetch_skb_u8(skb); } err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, Loading Loading
net/ieee802154/6lowpan.c +38 −32 Original line number Diff line number Diff line Loading @@ -291,25 +291,26 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) *hc06_ptr += 2; } static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) { u8 ret; if (unlikely(!pskb_may_pull(skb, 1))) return -EINVAL; ret = skb->data[0]; *val = skb->data[0]; skb_pull(skb, 1); return ret; return 0; } static u16 lowpan_fetch_skb_u16(struct sk_buff *skb) static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) { u16 ret; BUG_ON(!pskb_may_pull(skb, 2)); if (unlikely(!pskb_may_pull(skb, 2))) return -EINVAL; ret = skb->data[0] | (skb->data[1] << 8); *val = skb->data[0] | (skb->data[1] << 8); skb_pull(skb, 2); return ret; return 0; } static int Loading @@ -318,7 +319,8 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) struct udphdr *uh = udp_hdr(skb); u8 tmp; tmp = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &tmp)) goto err; if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { pr_debug("(%s): UDP header uncompression\n", __func__); Loading Loading @@ -710,7 +712,9 @@ lowpan_process_data(struct sk_buff *skb) /* at least two bytes will be used for the encoding */ if (skb->len < 2) goto drop; iphc0 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc0)) goto drop; /* fragments assembling */ switch (iphc0 & LOWPAN_DISPATCH_MASK) { Loading @@ -722,8 +726,9 @@ lowpan_process_data(struct sk_buff *skb) u16 tag; bool found = false; len = lowpan_fetch_skb_u8(skb); /* frame length */ tag = lowpan_fetch_skb_u16(skb); if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ goto drop; /* * check if frame assembling with the same tag is Loading @@ -747,7 +752,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) goto unlock_and_drop; offset = lowpan_fetch_skb_u8(skb); /* fetch offset */ if (lowpan_fetch_skb_u8(skb, &offset)) /* fetch offset */ goto unlock_and_drop; /* if payload fits buffer, copy it */ if (likely((offset * 8 + skb->len) <= frame->length)) Loading @@ -769,7 +775,10 @@ lowpan_process_data(struct sk_buff *skb) dev_kfree_skb(skb); skb = frame->skb; kfree(frame); iphc0 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc0)) goto unlock_and_drop; break; } spin_unlock(&flist_lock); Loading @@ -780,7 +789,8 @@ lowpan_process_data(struct sk_buff *skb) break; } iphc1 = lowpan_fetch_skb_u8(skb); if (lowpan_fetch_skb_u8(skb, &iphc1)) goto drop; _saddr = mac_cb(skb)->sa.hwaddr; _daddr = mac_cb(skb)->da.hwaddr; Loading @@ -791,9 +801,8 @@ lowpan_process_data(struct sk_buff *skb) if (iphc1 & LOWPAN_IPHC_CID) { pr_debug("(%s): CID flag is set, increase header with one\n", __func__); if (!skb->len) if (lowpan_fetch_skb_u8(skb, &num_context)) goto drop; num_context = lowpan_fetch_skb_u8(skb); } hdr.version = 6; Loading @@ -805,9 +814,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */ case 0: /* 00b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); memcpy(&hdr.flow_lbl, &skb->data[0], 3); skb_pull(skb, 3); hdr.priority = ((tmp >> 2) & 0x0f); Loading @@ -819,9 +828,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + DSCP (1 byte), Flow Label is elided */ case 1: /* 10b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); hdr.priority = ((tmp >> 2) & 0x0f); hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); hdr.flow_lbl[1] = 0; Loading @@ -832,9 +841,9 @@ lowpan_process_data(struct sk_buff *skb) * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */ case 2: /* 01b */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &tmp)) goto drop; tmp = lowpan_fetch_skb_u8(skb); hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); skb_pull(skb, 2); Loading @@ -853,9 +862,9 @@ lowpan_process_data(struct sk_buff *skb) /* Next Header */ if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ if (!skb->len) if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) goto drop; hdr.nexthdr = lowpan_fetch_skb_u8(skb); pr_debug("(%s): NH flag is set, next header is carried " "inline: %02x\n", __func__, hdr.nexthdr); } Loading @@ -864,9 +873,8 @@ lowpan_process_data(struct sk_buff *skb) if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I) hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03]; else { if (!skb->len) if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit))) goto drop; hdr.hop_limit = lowpan_fetch_skb_u8(skb); } /* Extract SAM to the tmp variable */ Loading Loading @@ -894,10 +902,8 @@ lowpan_process_data(struct sk_buff *skb) pr_debug("(%s): destination address non-context-based" " multicast compression\n", __func__); if (0 < tmp && tmp < 3) { if (!skb->len) if (lowpan_fetch_skb_u8(skb, &prefix[1])) goto drop; else prefix[1] = lowpan_fetch_skb_u8(skb); } err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, Loading