From 262f9ecc81ad911d7d319df3b9e286d1da31fcde Mon Sep 17 00:00:00 2001 From: Niklas Kullberg Date: Tue, 9 May 2023 10:06:27 +0200 Subject: [PATCH] fix(ip4defrag): allow final fragment to be less than 8 octets --- ip4defrag/defrag.go | 2 +- ip4defrag/defrag_test.go | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ip4defrag/defrag.go b/ip4defrag/defrag.go index 2fdac78cb..d9ee58a7e 100644 --- a/ip4defrag/defrag.go +++ b/ip4defrag/defrag.go @@ -176,7 +176,7 @@ func (d *IPv4Defragmenter) securityChecks(ip *layers.IPv4) error { fragSize := ip.Length - uint16(ip.IHL)*4 // don't allow small fragments outside of specification - if fragSize < IPv4MinimumFragmentSize { + if ip.Flags&layers.IPv4MoreFragments != 0 && fragSize < IPv4MinimumFragmentSize { return fmt.Errorf("defrag: fragment too small "+ "(handcrafted? %d < %d)", fragSize, IPv4MinimumFragmentSize) } diff --git a/ip4defrag/defrag_test.go b/ip4defrag/defrag_test.go index f42c45bd8..63d29e819 100644 --- a/ip4defrag/defrag_test.go +++ b/ip4defrag/defrag_test.go @@ -165,12 +165,31 @@ func TestDefragTooSmall(t *testing.T) { Flags: layers.IPv4MoreFragments, } if _, err := defrag.DefragIPv4(&ip1); err == nil { - t.Fatal("defrag: Minimum fragment size is supposed to be 8") + t.Fatal("defrag: Minimum fragment size is supposed to be 8, except for the final fragment") } ip1.Length++ if _, err := defrag.DefragIPv4(&ip1); err != nil { - t.Fatalf("defrag: Minimum fragment size is supposed to be 8, %s", err) + t.Fatalf("defrag: Minimum fragment size is supposed to be 8, except for the final fragment, %s", err) + } +} + +func TestDefragSmallFinalFragment(t *testing.T) { + defrag := NewIPv4Defragmenter() + + ip1 := layers.IPv4{ + Version: 4, + IHL: 5, + TTL: 15, + SrcIP: net.IPv4(1, 1, 1, 1), + DstIP: net.IPv4(2, 2, 2, 2), + Id: 0xcc, + FragOffset: 0, + Length: 27, // Minimum fragment size -1 + header (20) + Flags: 0, // Indicate final fragment + } + if _, err := defrag.DefragIPv4(&ip1); err != nil { + t.Fatal("defrag: Fragment size smaller than 8 should be allowed for the final fragment") } }