From: Stephen Hemminger <stephen@networkplumber.org>
To: "Morten Brørup" <mb@smartsharesystems.com>
Cc: <dev@dpdk.org>, <stable@dpdk.org>,
"Konstantin Ananyev" <konstantin.ananyev@huawei.com>
Subject: Re: [PATCH 2/6] ip_frag: discard datagrams with overlapping fragments
Date: Mon, 22 Jun 2026 08:03:59 -0700 [thread overview]
Message-ID: <20260622080359.28ab3022@phoenix.local> (raw)
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35F65934@smartserver.smartshare.dk>
On Mon, 22 Jun 2026 17:01:18 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, 19 June 2026 19.01
> >
> > On Fri, 19 Jun 2026 15:12:21 +0200
> > Morten Brørup <mb@smartsharesystems.com> wrote:
> >
> > > > + /*
> > > > + * Overlap with an existing fragment. Per RFC 8200 section
> > > > 4.5
> > > > + * (and RFC 5722) the datagram must be discarded; the same
> > > > is
> > > > + * applied to IPv4. Free all collected fragments, drop this
> > > > one,
> > > > + * and invalidate the entry.
> > > > + */
> > > > + if (ofs < fp->frags[i].ofs + fp->frags[i].len &&
> > > > + fp->frags[i].ofs < ofs + len) {
> > >
> > > This only catches fragments that are smaller than existing fragments,
> > i.e. fit within one of the existing fragments.
> > > It should be:
> > > if ((ofs >= fp->frags[i].ofs &&
> > > ofs < fp->frags[i].ofs + fp->frags[i].len) ||
> > > (ofs + len >= fp->frags[i].ofs &&
> > > ofs + len < fp->frags[i].ofs + fp->frags[i].len)) {
> > >
> > > > + ip_frag_free(fp, dr);
> >
> > The code here is comparing an incoming fragment N against existing
> > fragment E,
> > using half-open ranges [start, end).
> >
> > The test in the patch is symmetric in N and E.
> > ofs < e.ofs + e.len && e.ofs < ofs + len
> >
> > The one you propose tests that either endpoint of N lands inside E.
> >
> > Take a fixed stored fragment E = [200, 400) and run several incoming
> > fragments through both.
> > N0 = ofs, N1 = ofs+len.
> >
> > N inside E: N = [250, 300)
> >
> > E: |=========| (200..400)
> > N: |===| (250..300)
> >
> > Patch: 250 < 400 && 200 < 300 → T && T → overlap.
> > Proposed: (250≥200 && 250<400) → T → overlap.
> > Both agree.
> >
> > N encloses E: N = [100, 500)
> >
> > E: |=========| (200..400)
> > N: |=============| (100..500)
> >
> > Patch: 100 < 400 && 200 < 500 → T && T → overlap.
> > Proposed: (100≥200 && …) → F, (500≥200 && 500<400) → T && F → F, so F
> > || F → no overlap, MISSED.
> >
> > This is the case the new version version drops. Neither endpoint of N
> > (100 or 500) sits inside [200,400),
> > because N straddles E completely, so new version endpoint-in-E check
> > fails even though the ranges clearly overlap.
> > Patch version catches it because the interval test doesn't care which
> > range is larger.
> >
> > N partial on the left: N = [100, 300)
> >
> > E: |=========| (200..400)
> > N: |======| (100..300)
> >
> > Patch: 100 < 400 && 200 < 300 → T → overlap.
> > Proposed: (300≥200 && 300<400) → T → overlap.
> > Agree.
> >
> > N partial on the right: N = [300, 500) — symmetric to the above, both
> > catch it.
> >
> > So on the four genuine-overlap geometries, your suggestion catches all
> > four and his misses the enclosing one.
> > That is not right since the enclosing overlap is a legitimate attack
> > shape (a big fragment overwriting a smaller stored one).
> >
> > There is another issue.
> > The >= on the exclusive end produces a false positive on fragments that
> > merely abut, which is the normal case.
> > Take E already stored as [1400, 2800) and an in-order-but-late fragment
> > N = [0, 1400) arriving after it (ordinary out-of-order delivery):
> >
> > N: |======| (0..1400)
> > E: |======| (1400..2800)
> >
> > These share no bytes; byte 1400 belongs only to E.
> > Patch: 0 < 2800 && 1400 < 1400 → T && F → no overlap, correct.
> > Proposed: (1400≥1400 && 1400<2800) → T && T → overlap, wrong.
> > This test would discard a perfectly valid datagram whenever a left-
> > abutting fragment arrives after its neighbor.
> > Adjacent fragments abutting is what fragmentation produces by design,
> > so this would fire constantly under reordering.
> >
> > Bottom line: the patch was correct as far as I can tell.
>
> Thank you for the detailed explanation, Stephen.
> Agreed, and sorry about the noise. :-)
>
I will give credit to Claude for the detail. I reviewed the general
code here; but had to prod it into giving a more detailed explaination
because it was confusing..
next prev parent reply other threads:[~2026-06-22 15:04 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 21:05 [PATCH 0/6] ip_frag: fix reassembly defects and add test Stephen Hemminger
2026-06-16 21:05 ` [PATCH 1/6] ip_frag: tolerate duplicate fragments Stephen Hemminger
2026-06-16 21:05 ` [PATCH 2/6] ip_frag: discard datagrams with overlapping fragments Stephen Hemminger
2026-06-19 13:12 ` Morten Brørup
2026-06-19 17:01 ` Stephen Hemminger
2026-06-22 15:01 ` Morten Brørup
2026-06-22 15:03 ` Stephen Hemminger [this message]
2026-06-16 21:05 ` [PATCH 3/6] ip_frag: include protocol in IPv4 reassembly key Stephen Hemminger
2026-06-16 21:05 ` [PATCH 4/6] ip_frag: drop IPv6 fragments with unexpected headers Stephen Hemminger
2026-06-16 21:05 ` [PATCH 5/6] ip_frag: reject oversized reassembled datagrams Stephen Hemminger
2026-06-16 21:05 ` [PATCH 6/6] app/test: add test for IP reassembly Stephen Hemminger
2026-06-19 13:24 ` [PATCH 0/6] ip_frag: fix reassembly defects and add test Morten Brørup
2026-06-22 15:03 ` Morten Brørup
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260622080359.28ab3022@phoenix.local \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@huawei.com \
--cc=mb@smartsharesystems.com \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.