mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 10:03:50 +01:00
Merge pull request #21937 from miri64/gnrc_ipv6_ext_frag/fix/corner-cases
gnrc_ipv6_ext_frag: fix some corner cases
This commit is contained in:
commit
f19f1c6063
@ -423,6 +423,10 @@ gnrc_pktsnip_t *gnrc_ipv6_ext_frag_reass(gnrc_pktsnip_t *pkt)
|
||||
DEBUG("ipv6_ext_frag: unable to mark fragmentation header\n");
|
||||
goto error_release;
|
||||
}
|
||||
else if (pkt->size == 0) {
|
||||
DEBUG("ipv6_ext_frag: fragment empty after removing header\n");
|
||||
goto error_release;
|
||||
}
|
||||
fh = fh_snip->data;
|
||||
/* search IPv6 header */
|
||||
ipv6_snip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
|
||||
@ -524,6 +528,11 @@ gnrc_pktsnip_t *gnrc_ipv6_ext_frag_reass(gnrc_pktsnip_t *pkt)
|
||||
DEBUG("ipv6_ext_frag: fragment length not divisible by 8");
|
||||
goto error_exit;
|
||||
}
|
||||
else if (rbuf->pkt != NULL && rbuf->pkt->size < pkt->size) {
|
||||
DEBUG("ipv6_ext_frag: reassembly buffer too small to fit first "
|
||||
"fragment\n");
|
||||
goto error_exit;
|
||||
}
|
||||
_set_nh(fh_snip->next, nh);
|
||||
gnrc_pktbuf_remove_snip(pkt, fh_snip);
|
||||
/* TODO: RFC 8200 says "- 8"; determine if `sizeof(ipv6_ext_frag_t)` is
|
||||
|
||||
@ -157,6 +157,39 @@ def test_reass_offset_too_large(child, iface, hw_dst, ll_dst, ll_src):
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_reass_empty_fragment(child, iface, hw_dst, ll_dst, ll_src):
|
||||
# Originally proposed by Nils Bernsdorf (Uni Saarland), adapted by Martine Lenders
|
||||
# send the first packet (without payload) to initialize the reassembly buffer
|
||||
# with a null pointer
|
||||
sendp(Ether(dst=hw_dst) / IPv6(dst=ll_dst, src=ll_src) /
|
||||
IPv6ExtHdrFragment(id=0xabcd, nh=0, m=1, offset=0),
|
||||
iface=iface, verbose=0)
|
||||
# send the second packet to potentially trigger a memcpy
|
||||
sendp(Ether(dst=hw_dst) / IPv6(dst=ll_dst, src=ll_src) /
|
||||
IPv6ExtHdrFragment(id=0xabcd, nh=0, m=1, offset=0) /
|
||||
(b"A" * (24 - 8)),
|
||||
iface=iface, verbose=0)
|
||||
time.sleep(11) # let reassembly buffer garbage collect
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_reass_first_fragment_repeat(child, iface, hw_dst, ll_dst, ll_src):
|
||||
# Originally proposed by Nils Bernsdorf (Uni Saarland), adapted by Martine Lenders
|
||||
# send the first packet to initialize the reassembly buffer
|
||||
sendp(Ether(dst=hw_dst) / IPv6(dst=ll_dst, src=ll_src) /
|
||||
IPv6ExtHdrFragment(id=0xabcd, nh=0, m=1, offset=0) /
|
||||
(b"A"*(24-8)),
|
||||
iface=iface, verbose=0)
|
||||
# send the a second larger packet (also with offset 0) to trigger the buffer
|
||||
# overflow
|
||||
sendp(Ether(dst=hw_dst) / IPv6(dst=ll_dst, src=ll_src) /
|
||||
IPv6ExtHdrFragment(id=0xabcd, nh=0, m=1, offset=0) /
|
||||
(b"A"*(128-8)),
|
||||
iface=iface, verbose=0)
|
||||
# the fragments should be discarded
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_shell_test_0(child, s, iface, ll_dst):
|
||||
child.sendline("test {} 0".format(ll_dst))
|
||||
data, _ = s.recvfrom(RECV_BUFSIZE)
|
||||
@ -428,6 +461,8 @@ def testfunc(child):
|
||||
run(test_reass_successful_udp)
|
||||
run(test_reass_too_short_header)
|
||||
run(test_reass_offset_too_large)
|
||||
run(test_reass_empty_fragment)
|
||||
run(test_reass_first_fragment_repeat)
|
||||
print("SUCCESS")
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user