All of 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 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.