Skip to content

[handler] bound encap inner packet and fix MTU header-length undercount (APO-665, APO-667)#2

Merged
dilyevsky merged 1 commit into
mainfrom
dsky/apo-665-667-encap-bounds
Jun 16, 2026
Merged

[handler] bound encap inner packet and fix MTU header-length undercount (APO-665, APO-667)#2
dilyevsky merged 1 commit into
mainfrom
dsky/apo-665-667-encap-bounds

Conversation

@dilyevsky

Copy link
Copy Markdown
Contributor

Two data-plane correctness/safety fixes in the encap path.

APO-665 (MTU)

headerLength() built the Geneve header literal with both options populated but left NumOptions at 0, so MarshalBinary skipped the option loop and returned the 8-byte base length. MTU() therefore under-counted encapsulation overhead by 24 bytes and over-advertised the virtual-network MTU, letting the inner stack emit packets whose encapsulated size exceeds the path MTU (fragmentation / black-holing). Set NumOptions: 2 to match the fixed 2-option header the datapath emits (geneveHdrLen = 32).

APO-667 (encap overflow)

Neither encap path bounded the inner IP packet, so AES-GCM Seal (ciphertext + 16-byte tag) could be written past the end of the destination frame. On the AF_XDP datapath FrameFull caps the slice, so an oversized inner packet forces Seal to silently reallocate onto the heap — leaving plaintext in the UMEM frame the descriptor still points at; an external EngineXfrm/vtep caller passing a buffer whose capacity spans the next frame gets the literal adjacent-memory write. Both data-carrying encap paths (VirtToPhyInPlace, VirtToPhy) now drop and count a TX error when inner+tag would not fit. The keep-alive seals carry an empty plaintext and are unaffected.

Tests

util_test.go pins headerLength()/MTU() against the full overhead; oversized_inner_test.go drives an inner packet sized so the tag spills the frame edge and asserts a drop with an intact canary in the buffer tail (plus a boundary case that the max-sized packet still encapsulates). All four fail without the fixes. go vet, root go test, and GOOS=linux build are green.

🤖 Generated with Claude Code

…nt (APO-665, APO-667)

Two data-plane correctness/safety fixes in the encap path.

APO-665 (MTU): headerLength() built the Geneve header literal with both
options populated but left NumOptions at 0, so MarshalBinary skipped the
option loop and returned the 8-byte base length. MTU() therefore
under-counted encapsulation overhead by 24 bytes and over-advertised the
virtual-network MTU, letting the inner stack emit packets whose
encapsulated size exceeds the path MTU (fragmentation / black-holing).
Set NumOptions: 2 to match the fixed 2-option header the datapath emits
(geneveHdrLen = 32).

APO-667 (encap overflow): neither encap path bounded the inner IP packet,
so AES-GCM Seal (ciphertext + 16-byte tag) could be written past the end
of the destination frame. On the AF_XDP datapath FrameFull caps the slice,
so an oversized inner packet forces Seal to silently reallocate onto the
heap -- leaving plaintext in the UMEM frame the descriptor still points at;
an external EngineXfrm/vtep caller passing a buffer whose capacity spans
the next frame gets the literal adjacent-memory write. Both data-carrying
encap paths (VirtToPhyInPlace, VirtToPhy) now drop and count a TX error
when inner+tag would not fit. The keep-alive seals carry an empty plaintext
and are unaffected.

Tests: util_test.go pins headerLength()/MTU() against the full overhead;
oversized_inner_test.go drives an inner packet sized so the tag spills the
frame edge and asserts a drop with an intact canary in the buffer tail
(plus a boundary case that the max-sized packet still encapsulates). All
four fail without the fixes. go vet, root go test, and GOOS=linux build
are green.
@linear-code

linear-code Bot commented Jun 16, 2026

Copy link
Copy Markdown

APO-665

APO-667

@dilyevsky dilyevsky merged commit 2f1f26e into main Jun 16, 2026
3 of 4 checks passed
@dilyevsky dilyevsky deleted the dsky/apo-665-667-encap-bounds branch June 16, 2026 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant