Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc_ipv6: fix UDP issue #5926

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,9 @@ static void _receive(gnrc_pktsnip_t *pkt)
ipv6 = gnrc_pktbuf_mark(pkt, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6);

first_ext = pkt;
#ifndef MODULE_GNRC_SIXLOWPAN
pkt->type = GNRC_NETTYPE_UNDEF; /* snip is no longer IPv6 */
Copy link
Contributor

@Yonezawa-T2 Yonezawa-T2 Oct 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line makes sense only for 6LoWPAN packets. See #5596 (comment). So #ifndef MODULE_GNRC_SIXLOWPAN doesn't make sense.
If we doesn't set pkt->type = GNRC_NETTYPE_UNDEF when the 6LoWPAN module is enabled, other modules (e.g. gnrc_icmpv6, gnrc_udp) will be confused because a snip without IPv6 header is marked as a IPv6 snip. Recall #5596 (comment).

[edit]pkt->type is updated gnrc_ipv6_demux, so this does not affect gnrc_icmpv6 or gnrc_udp. [/edit]

#endif

if (ipv6 == NULL) {
DEBUG("ipv6: error marking IPv6 header, dropping packet\n");
Expand Down Expand Up @@ -888,11 +890,19 @@ static void _receive(gnrc_pktsnip_t *pkt)
if (byteorder_ntohs(hdr->len) < pkt->size) {
gnrc_pktbuf_realloc_data(pkt, byteorder_ntohs(hdr->len));
}
#ifdef MODULE_GNRC_SIXLOWPAN
else if (byteorder_ntohs(hdr->len) >
(gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the node have both 6LoWPAN and IPv6 interface, this condition may not catch invalid packets.

Running debugger on tests/gnrc_ipv6_ext with 6LoWPAN enabled (i.e. adding USEMODULE += gnrc_sixlowpan_default to the Makefile) shows gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) == 82 while byteorder_ntohs(hdr->len) == 42 because the former includes IPv6 header. So, a malicious packet with byteorder_ntohs(hdr->len) == 82 will pass this validation even if its actual length is 42.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this is my biggest problem with this PR too. Please add a check if the interface is a 6LoWPAN interface + leave the check below in.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(second only if GNRC_NETIF_NUM > 1)

DEBUG("ipv6: invalid payload length: %d, actual: %d, dropping packet\n",
(int) byteorder_ntohs(hdr->len),
(int) (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6)));
#else
else if (byteorder_ntohs(hdr->len) >
(gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t))) {
DEBUG("ipv6: invalid payload length: %d, actual: %d, dropping packet\n",
(int) byteorder_ntohs(hdr->len),
(int) (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t)));
#endif /* MODULE_GNRC_SIXLOWPAN */
gnrc_pktbuf_release(pkt);
return;
}
Expand Down