DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
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: Fri, 19 Jun 2026 10:01:24 -0700	[thread overview]
Message-ID: <20260619100124.655e5540@phoenix.local> (raw)
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35F6592A@smartserver.smartshare.dk>

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.

  reply	other threads:[~2026-06-19 17:01 UTC|newest]

Thread overview: 10+ 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 [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

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=20260619100124.655e5540@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox