untrusted comment: verify with openbsd-76-base.pub
RWTkuwn4mbq8otkice67Au+qa46kleyAePGu+I4hLM1qXHhaGRct3M8ZlT+TTajWJwWpqA2jexBW6MWGVmekhVdgzT8pi2KIiQo=

OpenBSD 7.6 errata 007, February 10, 2025:

pf(4) could reassemble overlapping fragments into an incorrect IP
packet that was too short.

Apply by doing:
    signify -Vep /etc/signify/openbsd-76-base.pub -x 007_pffrag.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/net/pf_norm.c
===================================================================
RCS file: /cvs/src/sys/net/pf_norm.c,v
diff -u -p -r1.233 pf_norm.c
--- sys/net/pf_norm.c	14 Jul 2024 18:53:39 -0000	1.233
+++ sys/net/pf_norm.c	1 Feb 2025 22:14:25 -0000
@@ -667,34 +667,21 @@ pf_fillup_fragment(struct pf_frnode *key
 
 		aftercut = frent->fe_off + frent->fe_len - after->fe_off;
 		if (aftercut < after->fe_len) {
-			int old_index, new_index;
-
 			DPFPRINTF(LOG_NOTICE, "frag tail overlap %d", aftercut);
 			m_adj(after->fe_m, aftercut);
-			old_index = pf_frent_index(after);
+			/* Fragment may switch queue as fe_off changes */
+			pf_frent_remove(frag, after);
 			after->fe_off += aftercut;
 			after->fe_len -= aftercut;
-			new_index = pf_frent_index(after);
-			if (old_index != new_index) {
-				DPFPRINTF(LOG_DEBUG, "frag index %d, new %d",
-				    old_index, new_index);
-				/* Fragment switched queue as fe_off changed */
-				after->fe_off -= aftercut;
-				after->fe_len += aftercut;
-				/* Remove restored fragment from old queue */
-				pf_frent_remove(frag, after);
-				after->fe_off += aftercut;
-				after->fe_len -= aftercut;
-				/* Insert into correct queue */
-				if (pf_frent_insert(frag, after, prev)) {
-					DPFPRINTF(LOG_WARNING,
-					    "fragment requeue limit exceeded");
-					m_freem(after->fe_m);
-					pool_put(&pf_frent_pl, after);
-					pf_status.fragments--;
-					/* There is not way to recover */
-					goto free_fragment;
-				}
+			/* Insert into correct queue */
+			if (pf_frent_insert(frag, after, prev)) {
+				DPFPRINTF(LOG_WARNING,
+				    "fragment requeue limit exceeded");
+				m_freem(after->fe_m);
+				pool_put(&pf_frent_pl, after);
+				pf_status.fragments--;
+				/* There is not way to recover */
+				goto free_fragment;
 			}
 			break;
 		}