Vulnerability Research
Why Did One Plaintext Page Turn Into Ciphertext Outside the Tunnel? Tracing the Lost Ownership Bit in IP-TFS (CVE-2026-53363)
CVE-2026-53363 begins with a zero-copy transfer that delivered the data, length, and page references intact yet left behind the single bit that answers whether those bytes may be changed in place, and this report follows a page still owned by a file or pipe through IP-TFS aggregation, skb fragment transfer, and ESP encryption to show why a two-line fix restores a cross-subsystem ownership contract.

In this article
The story begins on a memory page that does not belong exclusively to the network stack. It may still be part of a file's page cache, may just have entered a pipe through vmsplice(), or may remain referenced by another consumer. An application wants to avoid unnecessary copying, so Linux carries the bytes downward as nonlinear skb fragments. That can be both fast and safe as long as every handoff remembers that the page remains externally shared: readers may share it, but a writer must first create private storage.
When IP-TFS receives this page, it is not merely forwarding one IP packet. It reshapes, aggregates, and pads several inner packets so an observer has a harder time recovering their lengths and timing. A 2024 optimization avoided copying page-backed payloads a second time by moving the source skb's fragment descriptors into a new aggregate skb. The descriptors arrived, and page-release responsibility moved with them. SKBFL_SHARED_FRAG did not.
Losing one bit does not immediately crash the kernel. The aggregate skb can still queue; its lengths remain right; ESP can emit a well-formed ciphertext packet; and the remote peer may decrypt it correctly. The mistake becomes real at a quieter moment. ESP concludes that the pages are privately writable, skips copy-on-write, and replaces plaintext with ciphertext in place. The network operation appears successful while another owner outside the tunnel finds that its bytes have silently changed.
CVE-2026-53363 is therefore more than a mechanical failure to copy a flag. It is a cross-subsystem ownership contract cut in half. IP-TFS reshapes traffic, the skb layer describes storage, and ESP transforms bytes. Each layer can make a locally reasonable decision and still produce a globally unsafe result. The missing boundary appears only when the same page is followed from its origin to the first write.
This report does not rely on destructive exploit code. We use the public Linux CNA record, upstream introducing and fixing commits, RFC 9347, the kernel's sk_buff documentation, and the IPv4 and IPv6 ESP source. Local work is limited to static diffs and controlled ownership reasoning. The result is a precise account of the required conditions, why normal tunnel tests miss the defect, how to assess vendor backports, and how to turn this case into a reusable zero-copy review method.
Keep one sentence in view throughout the investigation: a page reference proves that the memory remains alive; a shared-fragment flag proves that the current skb may not treat it as exclusively writable. Every consequence of CVE-2026-53363 follows from confusing those two statements.
1 How a Successful Send Left Its Original Page Rewritten
1.1 The tunnel reported no fault; the fault happened outside it
Consider a Linux gateway serving as an encrypted egress. An application sends part of a file to a socket. Instead of copying every byte into a new contiguous buffer, the kernel lets an skb refer directly to pages that already contain the data. IP-TFS combines several such inner packets into a more uniform payload, and ESP encrypts the result. A packet capture shows orderly sequence numbers and a valid authentication tag; the peer decrypts the expected bytes. By an ordinary network acceptance test, the send is flawless.
Now fingerprint the original file page or the retained pipe data immediately before the send and again after it. On a vulnerable kernel, that second view can tell a different story: the ciphertext on the wire is correct, but the memory lent to the network stack contains portions of the transformed output. The peer sees a successful transfer while the data source bears the failure. A test that asks only whether two endpoints can communicate will miss it, and a monitor that sees only outer packets has little reason to raise an alert.
The behavior feels paradoxical because engineers often compress two propositions into one. “The skb owns a page reference” means the page cannot be freed while that reference remains. It does not mean the skb is the only observer. The page cache may still represent a file, a pipe consumer may still expect the producer's bytes, or another skb may still refer to the same page. The stack can safely read from that storage without a copy; it cannot infer that it may alter the storage in place.
The early portion of the send path is read-only. Code queues fragments, computes lengths, moves descriptors, and builds an aggregate layout without changing the referenced bytes. A lost ownership attribute can therefore remain dormant through many correct operations. ESP is the first stage that requires a writable payload. At that moment, the stale metadata becomes a consequential branch decision: the copy that should isolate the writer is omitted.
A useful investigation must consequently observe two worlds. The first is the IPsec result, which tells us whether the protocol operation still works. The second is the object that originally supplied the page, which tells us whether zero-copy honored its loan. Looking only at the first yields “success.” Looking at both reveals that success may have been purchased by changing storage that still belongs to someone else.
The public CNA record specifically describes read-only page-cache pages being encrypted in place by ESP. The code gives that result a broader ownership interpretation without licensing broader claims: any nonlinear fragment marked SKBFL_SHARED_FRAG, still visible outside the skb and routed through this exact transfer and write decision, relies on that bit to force private storage. We will keep confirmed outcomes separate from conditional implications throughout the report.
1.2 Three gates must open together; not every IPsec host has the same path
The first gate is active IP-TFS transmission. A conventional ESP tunnel, an XFRM state that does not use IP-TFS, or a machine that only receives and decapsulates traffic does not execute the vulnerable fragment-transfer operation for that direction. Kernel age tells us whether the code may exist. Configuration, direction, and counters tell us whether the code is reachable on this asset.
The second gate is a source skb whose nonlinear fragments are genuinely shared with an outside owner. If an upper layer already copied data into a private linear buffer, the missing bit remains a software defect but lacks an external page to corrupt in that send. Workloads involving sendfile(), splice(), vmsplice(), page-backed caches, and high-throughput frameworks deserve early attention, but the syscall name alone is not proof that a particular skb retained shared pages.
The third gate is an ESP layout that would otherwise permit in-place transformation. Both IPv4 and IPv6 implementations consider clone state, nonlinear data, frag lists, and the result of skb_has_shared_frag(). Only when the rest of the conditions make the existing fragments look writable does the missing bit change the branch. Another condition may accidentally force skb_cow_data() and hide the behavior in one test while leaving the underlying metadata wrong.
These gates explain why the same build can appear different across systems. A server with no IP-TFS state has no current path. A gateway using IP-TFS but always receiving private application buffers might not expose an outside observer. A high-volume file gateway that preserves page-backed fragments is much closer to the scenario in the CNA record. A complete exposure model therefore combines build, configuration, source storage, and write-path evidence; a version list supplies only the first coordinate.
The same model provides a safe test. In an isolated environment, give a page known content and keep a second legitimate observer. Verify that the skb enters IP-TFS with the shared bit, that the destination retains it after fragment transfer, and that ESP writes only to a private copy. This proves the ownership invariant directly; it does not require an out-of-bounds primitive, production data, or any attempt to amplify the consequence.
We can now state the investigation as three concrete questions. Which function moved the fragments? Which fact did that function fail to move? Which later consumer trusted the missing fact before writing? The next chapter enters Linux's implementation of RFC 9347 and shows how an optimization intended to reduce both traffic leakage and memory copying linked those distant decisions.
2 IP-TFS Packs Different Rhythms Into One Envelope
2.1 RFC 9347 shapes traffic; Linux must also account for bytes and pages
Conventional IPsec hides payload content but can still expose packet length, packet count, and timing. A short interactive request, a sustained file transfer, and periodic heartbeats may retain distinct shapes even when every payload is encrypted by ESP. IP Traffic Flow Security, standardized in RFC 9347, adds aggregation, fragmentation, and padding before ESP so the sender can produce a more controlled outer stream and reduce those side-channel clues.
The protocol treats inner packets as records that can be arranged in an IP-TFS stream. The implementation must make lower-level decisions: where every byte resides, which object releases its page, and whether existing storage may be reused when a later stage writes. Linux XFRM queues prepared skbs, consumes enough bytes to construct an output skb, and may divide one inner packet across output boundaries or place several complete packets into one aggregate.
The safest ownership design would allocate a fresh contiguous buffer for every aggregate and copy all inner payloads. It would also surrender much of the zero-copy work that makes high-throughput gateways efficient. When payload bytes already live in pages, moving skb_frag_t descriptors is cheaper than copying the bytes. Introducing commit b96ba312e21c brought precisely that page-fragment sharing optimization to IP-TFS.
Moving a descriptor does not move the physical page. A descriptor carries a page reference, offset, and length. After the transfer, the destination skb becomes responsible for releasing that reference, and the source no longer counts the fragment in nr_frags. The data may never leave its original page. What changes is the network object's responsibility for the reference and the conclusions downstream code draws about that page.
Every semantic property attached to the page must travel with the descriptor. Length controls the readable region; reference ownership controls lifetime; checksum and accounting state influence network processing; the shared-fragment flag controls write permission. Copying the visible payload description while omitting that last property resembles handing an original document to a new custodian but leaving behind the “do not annotate” seal.
IP-TFS's privacy purpose makes the seal especially important. The aggregate will ordinarily be handed straight to ESP for transformation. A write is not a rare side effect but the expected end of the send path. An ownership defect that could remain latent in read-only forwarding receives a dependable write trigger when aggregation is followed by encryption.
2.2 Five handoffs connect a local optimization to the eventual write
The first handoff is the upper send path. An skb may have a linear head and several page fragments. If those pages remain affected by an external owner, the network stack records SKBFL_SHARED_FRAG in skb_shared_info.flags. The bit does not merely say that the skb structure was cloned, and it is not another spelling of the page reference count. It says that nonlinear storage may still be observed or altered outside this skb.
The second handoff is the IP-TFS queue. Output logic calculates how much room remains, consumes complete or partial inner packets, and schedules any remainder. Queue management manipulates offsets, lengths, padding, and timing; it need not change the plaintext in the referenced pages. Vulnerable and fixed kernels therefore remain externally indistinguishable through this stage.
The third handoff is iptfs_consume_frags(). When source fragments can be adopted, it appends their descriptors to the destination array, increases the destination's fragment count, and clears the source count. That last write is the signature of an ownership transfer: source destruction must no longer release the pages, while the destination assumes that future responsibility.
The fourth handoff is XFRM/ESP output preparation. ESP needs head and tail space, authentication material, and a payload the cipher may modify. The code decides whether to use the current fragments or obtain copy-on-write storage. It must trust the shared state inherited at the previous handoff because ESP has no independent knowledge of whether a page originated in a file, pipe, cache, or another producer.
The fifth handoff is the cryptographic transformation itself. The algorithm writes plaintext into ciphertext along the scatterlist it receives. With a correct decision, an outside owner retains plaintext while a private network page carries ciphertext. With the wrong decision, the cipher still performs exactly the operation requested, but the target happens to be storage that another object can see. The cryptographic code does not cross a buffer boundary; it receives a false statement about writability.
A correct fix should therefore not disable all in-place ESP encryption. Doing so would penalize genuinely private fragments and would conceal the incomplete metadata transfer. The right repair belongs at the third handoff, where the code knows which descriptors move from which source into which destination. Restore the fact there, and the existing fourth-stage protection makes the right choice.
This chain is also why reading only the two-line patch produces an impoverished report. The OR assignment identifies a lost bit. The ESP source shows that the bit controls an actual copy. The original page owner shows why that copy protects data outside the packet. Our narrative follows the same investigative direction: from the strange outcome, back through the decisive branch, to the fact that disappeared.
3 One Memory Page Has Two Ledgers: Lifetime and Write Authority
3.1 A reference count preserves life; it does not grant exclusive write access
A struct sk_buff does not require all packet bytes to occupy one contiguous allocation. Its linear area usually holds headers and some data, while frags[] in skb_shared_info describes page-backed regions. Each entry identifies a page, offset, and length. Several entries may refer to different pages, and more than one object may hold references to the same physical page.
The first ledger is lifetime. As long as the destination skb holds a reference, destroying the source must not free the physical page. When the destination finally dies, it must return the reference exactly once. Clearing the source nr_frags after iptfs_consume_frags() transfers descriptors prevents both skbs from behaving as the releasing owner. Errors in this ledger commonly become premature frees, double releases, or leaks.
The second ledger is writability. A live page need not be private. The page cache may still need to represent file content; a pipe consumer may expect the producer's original bytes; another skb may share the same storage. Perfect reference accounting can coexist with an unsafe write. SKBFL_SHARED_FRAG is the conspicuous entry in this second ledger that tells future writers not to mistake survival for exclusivity.
The ledgers are easy to conflate because “taking a reference” sounds like complete sharing management. It answers only whether storage may be reclaimed. During a read-only operation, a private page and a shared page behave identically. They diverge when a writer arrives. Copy-on-write turns a page that is both live and shared into separate pages that remain live and become independently writable.
skb_clone() adds another sharing dimension: multiple skb structures can share packet data. ESP consequently considers clone/writable state and the external sharing of nonlinear pages. An skb that is not cloned does not necessarily own every referenced page exclusively. CVE-2026-53363 erased the fact needed to keep those propositions separate.
A source review should ask the two ledger questions independently. Who calls the eventual page release after the transfer? That establishes lifetime responsibility. Who can still observe or alter the bytes after the transfer? That establishes write authority. A new skb may be passed to an in-place transformer only after both answers are explicit.
3.2 SKBFL_SHARED_FRAG is an aggregate property: one shared member constrains the set
In the kernel header, SKBFL_SHARED_FRAG resides in skb_shared_info.flags. skb_has_shared_frag() reports sharing when the skb contains nonlinear data and the bit is set. The state applies to the fragment collection carried by that skb; it is not stored as a separate flag on every skb_frag_t.
That collection-level representation determines the merge rule: bitwise OR. If the destination already contains a shared fragment, appending a private one must not clear the constraint. If it was previously private, adding any shared source must set the constraint. Arrival order does not matter. The resulting object must preserve the strictest ownership condition represented by any member.
The fix additionally checks that the source nr_frags is nonzero. That detail prevents an empty skb with a stale flag from contaminating the destination. A collection property should move only when collection members actually move. No member means there is no current page-ownership fact to inherit.
The bit must be read before the source count becomes zero. After clearing, the source no longer semantically owns the fragments even if the raw flag remains in its structure. The patch places the OR before that boundary: it transfers the restriction while the source still describes the collection, then completes the ownership move.
Other network-core paths that merge or move fragments propagate this bit, providing useful cross-checking evidence. The operation is not an IP-TFS-specific workaround; it is part of the existing skb ownership model. The CNA also associates this case with the class represented by CVE-2026-46300, in which code retained page descriptors but lost SKBFL_SHARED_FRAG. That repetition turns a one-line mistake into a recognizable review pattern.
The lesson is not to forbid zero-copy. Shared pages are a legitimate and valuable performance mechanism, and the kernel already has a copy-on-write signal for them. The invariant is narrower and more durable: whenever descriptors are split, merged, or transferred without copying their pages, the collection's strictest ownership property must not be weakened.
Both ledgers are now reconciled. The destination correctly acquired page-release responsibility in the vulnerable implementation but did not acquire the restriction against writing shared storage. The next chapter zooms into the assignments where that restriction vanished and then follows the stale result into the ESP decision several layers later.
4 The Flag Disappears Before Zeroing; ESP Trusts the Result Layers Later
4.1 iptfs_consume_frags() moved the objects but not the collection's restriction
The vulnerable helper receives destination and source skbs and retrieves both skb_shared_info areas. It verifies room in the destination fragment array, then copies source frags[] entries to the destination tail. Only descriptor structures move; the page content stays where it is, preserving the zero-copy property the optimization was meant to deliver.
The function then adds the source count to destination nr_frags, updates accounting, and finally sets source nr_frags to zero. From a release-responsibility perspective, the sequence is coherent. The source will no longer release those references; the destination will. A review focused only on leaks and use-after-free behavior could reasonably pass this code.
The defect lies between the count updates. Source skb_shared_info.flags may contain SKBFL_SHARED_FRAG, yet no assignment transfers that bit to destination flags. Once the source count is cleared, the physical bit may remain in the empty source structure, but it no longer accompanies the pages it describes. The destination that actually owns the descriptors reports that none of them is externally shared.
This is a half-move. In a language with checked ownership, moving a value can prevent the source from being used as if it still owns the value. An skb transfer in C depends on the programmer to update arrays, counts, references, and flags together. Every field may look locally valid while the combined statement is false: the destination's description of its bytes is accurate, and its description of their writability is not.
The history clarifies intent. The introducing commit shared page fragments from inner packets to reduce copying while IP-TFS formed an outer packet. It did not add new cryptographic behavior or change parsing. The new page-ownership transfer path carried the regression; RFC 9347's protocol design remained unchanged.
Fix e9096a5a170e7ecd6467bc2e08668ec39897cda7 adds the essential operation when the source has fragments: toi->flags |= fromi->flags & SKBFL_SHARED_FRAG. The mask transfers only the relevant bit, OR preserves existing destination restrictions, and the placement precedes source-count clearing. No IP-TFS wire format changes.
Three counterexamples demonstrate the precision of the repair. A shared destination plus private source must remain shared. A private destination plus shared source must become shared. A source with no actual fragments must not change the destination because of stale flags. The patch gives the correct result in all three cases; an indiscriminate flags assignment would not.
4.2 IPv4 and IPv6 ESP both treat the bit as testimony for copy-on-write
Following the call chain into net/ipv4/esp4.c, output preparation decides whether the current skb can be handed directly to cryptographic processing. When the skb is not cloned, contains nonlinear data, lacks a complex frag list, and skb_has_shared_frag() is false, the implementation can use existing fragments. Otherwise, it must acquire a safe writable arrangement through mechanisms such as skb_cow_data().
net/ipv6/esp6.c contains the same class of decision. The issue is therefore not confined to one address-family branch. An inventory cannot dismiss it by saying that a deployment is IPv6-only or IPv4-only; the relevant question remains whether the vendor build routes IP-TFS output through an ESP path that consumes the shared-fragment result.
On a fixed kernel, the aggregate skb inherits the bit, skb_has_shared_frag() returns true, and the direct-write condition is denied. Copy-on-write creates private pages. The original file or pipe retains plaintext while the packet's private storage receives ciphertext. At the write boundary, the two observers finally occupy separate storage and can no longer interfere.
On a vulnerable kernel, the helper reports false. If the remaining conditions also allow the fast path, ESP treats the fragments as writable and the cipher overwrites the original bytes along its scatterlist. Because those descriptors still identify the page supplied upstream, a later file-cache or pipe reader sees transformed data. The network result can remain correct precisely because the overwritten bytes are the ciphertext ESP intended to transmit.
The cipher did not write at the wrong offset. Its caller supplied the wrong page. Replacing one cipher suite with another, or moving between software and hardware crypto, is not a general repair. Such changes may alter whether a particular test hits the in-place path, but they do not restore the lost ownership fact.
Likewise, observing skb_cow_data() during one run does not prove a build safe. Clone state, fragment shape, headroom, device behavior, or another condition may force a copy and mask the missing bit. Verification must establish the propagation itself and deliberately cover a controlled layout in which the shared bit is the deciding evidence.
The complete causal chain is now closed. The optimization introduced a descriptor-transfer path; that path omitted a collection property; ESP relied on the property to decide whether to copy; and in-place encryption turned stale state into an externally visible rewrite. Impact analysis can therefore move beyond a vague “memory corruption” label and identify the assets, evidence, and conditions that genuinely matter.
5 Narrow “Affected Version” Into the Gateways That Need Action
5.1 Four kinds of evidence must meet: code, configuration, page source, and write path
The first inventory layer is running code. The Linux CNA maps the introduction to b96ba312e21c9b7ac1526829b9640ddc06695c0b, an implementation that reached the upstream 6.14 era. Its public mapping identifies 6.18.36, 7.0.13, and 7.1 as fixed starting points for their lines. Those numbers are upstream coordinates, not a substitute for evidence about a distribution build.
Enterprise kernels routinely backport features and security fixes to different bases. A release string older than 6.14 can still carry IP-TFS; a string inside an upstream affected range may already carry an equivalent repair. A reliable conclusion uses the vendor advisory, source package, or build identity, then checks the actual property propagation in the function.
The second layer is active configuration. Capture XFRM state and policy with namespace, address family, endpoint, direction, mode, interface, and counters. Include configuration repositories and generated templates because an empty queue at inspection time does not prove a state cannot be created later. Short-lived gateway containers are particularly easy to miss between deployments.
Direction matters. The bad write occurs while forming IP-TFS output and handing it to ESP. A node that only decapsulates input has a different immediate priority from one that forwards in both directions. Standby members still belong in scope because failover can make an apparently idle host take over the same transmit role.
The third layer is how bytes reach the socket. File servers, object caches, proxies, backup channels, and high-throughput messaging systems frequently use page-backed paths. Application configuration, runtime libraries, syscall observation, and framework behavior must be considered together. A TLS or filtering layer may rebuild private buffers before XFRM; another stack may preserve the original page throughout.
vmsplice() deserves a distinct entry because user-backed pages can enter a pipe while the originating process retains an observable relationship. splice() can move references between pipes, files, and sockets, while sendfile() often carries page-cache content toward a socket. They are representative sources, not an exhaustive trigger list. The relevant fact is a nonlinear fragment marked shared.
The fourth layer is whether ESP may transform the fragments in place. Review vendor changes to esp4.c, esp6.c, hardware offload, and asynchronous crypto. A device may linearize some traffic or may hand page fragments directly to the algorithm. One model, MTU, or queue configuration cannot establish behavior for an entire fleet.
Preserve the four facts as one reviewable record: kernel build provenance and hash; active XFRM/IP-TFS configuration; the application-to-socket data path; and the ESP writability decision in that build. Code presence alone means “the vulnerable implementation is present.” All four aligning marks a scenario that deserves immediate controlled verification. This layered language prevents both panic and premature dismissal.
Do not search only devices labeled VPN gateway. IP-TFS may appear in traffic-shaping experiments, privacy networks, edge nodes, kernel test hosts, and cloud image templates. Expand discovery into configuration generators, base images, module packages, orchestration repositories, and fields that select XFRM modes.
Virtualization requires locating the kernel that actually executes xfrm_iptfs and ESP. If a guest builds the tunnel, the host version cannot answer for it. If a host namespace owns the tunnel, many containers can share one affected kernel. Counting the executing kernel instance is more accurate than multiplying by application containers.
Business impact depends on what the page represents. Regenerable temporary bytes may yield a transient integrity error; persistent page-cache content, multi-consumer messages, or sensitive plaintext can raise confidentiality and recovery consequences. The CVE score provides a common baseline, while data role and restoration cost determine local urgency.
Nor should a “local sender” condition be simplified into universally low local risk. A gateway can transmit bytes on behalf of tenants, proxy clients, or internal services. A principal able to influence the payload and its storage may not administer the gateway. The deployment determines who can shape the required conditions.
At the same time, the public result should not be inflated into automatic remote code execution. The verified chain is an incorrect in-place transformation of shared storage, with integrity and possible disclosure consequences. Any further effect requires evidence about the page's content and other consumers; speculation cannot substitute for that analysis.
5.2 The best field evidence is usually a silent change at the source, not an odd ciphertext packet
A network capture usually proves only that ESP output looks normal. Packet length, sequence, authentication, and successful peer decryption do not reveal whether ciphertext was written to a private page. Treating “no PCAP anomaly” as an exclusion criterion misses the defining reverse effect.
Source-side evidence is more informative. If file-integrity tooling records cached-content anomalies or validation failures near IP-TFS transmission, correlate timestamps with XFRM counters, source processes, and the transmitted file. Distinguish persistent disk changes from memory-only page-cache changes that disappear after invalidation or reread.
A pipe consumer may report an unparsable block, unexpectedly high-entropy bytes, or protocol validation failure. A condition in which identical producer data is normal over an ordinary socket but changes only under a particular IP-TFS policy is stronger evidence than one isolated application error. Preserve offsets and lengths so they can be compared with fragment boundaries.
The kernel may not crash or log a clear fault. Encryption writes through a valid mapping; the address access itself can be legal. KASAN, page faults, and ordinary bounds checks therefore need not trigger. The absence of an oops says little about whether ownership was correct.
Understand what an integrity sensor observes: disk blocks, page cache, or application reads. Disk hashes may remain stable until a dirty page is written back while an application already sees changed bytes. Another implementation may propagate the change differently. Constrain every report conclusion to the layer that the sensor actually measured.
Performance metrics can supply supporting evidence after repair. Shared-fragment traffic that now copies before writing may use more CPU or memory bandwidth than the vulnerable fast path. That is the cost of restoring isolation, not automatically a regression to revert. Verification must combine correctness and capacity.
For evidence preservation, record the running build ID, module hashes, boot parameters, XFRM state and policy, device capabilities, namespace mapping, relevant processes, and application versions. uname -r alone cannot reconstruct a vendor-backport case.
When collecting a suspicious file or pipe output, avoid repeated reads and retransmissions that alter cache or queue state. Work from an isolated copy, document collection time and method, and hash source content separately from outer packets. Existing authorization and retention controls continue to apply to sensitive data.
One observed content change also needs attribution. An application write, filesystem writeback, cache invalidation, test concurrency, or hardware fault can alter bytes. The strongest link is a change immediately around ESP transformation, matching transferred fragment ranges and appearing only in the build that lacks propagation.
Classify assets by evidence. Confirmed means the source lacks the fix and all path conditions are established. Probable means version and configuration are established while source or write behavior remains unobserved. Pending means only the build may be affected. This vocabulary focuses urgent action without turning unknowns green.
The inventory has now become an actionable queue, with a vague version list replaced by evidence tiers. The next chapter returns to patch history: why a masked OR is the right repair, how stable lines inherit it, and what semantics a vendor backport must preserve even when its text and commit identity differ.
6 The Two-Line Patch Repairs a Complete Handoff, Not Merely a Fast Path
6.1 Read the repair through four details: OR, mask, condition, and order
The first semantic detail is OR. A destination skb may already contain fragments from earlier sources, and its shared state represents the strictest restriction among them. An assignment could let a later private source erase an earlier shared fact. OR can add a constraint but cannot accidentally relax one. That monotonic behavior is exactly what an aggregate ownership property requires.
The second detail is the mask. Source flags may contain bits unrelated to this ownership question. The patch selects only SKBFL_SHARED_FRAG, avoiding an indiscriminate transplant of source-object state. A security repair must carry the needed fact without inventing new meaning for other bits.
The third detail is the fromi->nr_frags condition. The source's shared state affects the destination only when actual page fragments move. An empty source may retain an old flag after reuse or cleanup; basing propagation on a nonempty collection prevents a property with no members from creating a false restriction.
The fourth detail is order. Propagation occurs before fromi->nr_frags = 0. The sequence forms a semantic transaction: while the source still owns the collection, its restriction is read and inherited; then the source gives up the members. No new lock is required for the single execution path, but the ordering makes the ownership boundary provable.
A vendor backport must preserve all four details. A line that appears similar but checks the count after clearing may never execute. A plain assignment can still lose state with mixed sources. An unconditional flags copy can alter an empty-source case. Equivalent repair is a property of all combinations, not a visual resemblance to the upstream diff.
A compact review matrix helps: private destination/private source stays private; private/shared becomes shared; shared/private remains shared; shared/shared remains shared. Add a zero-fragment source variant to each cell and verify the destination does not change. This catches semantic errors even if a vendor has reorganized the function.
Search vendor trees for alternate paths. A distribution may inline the helper, add batch transfers, or carry a device-specific optimization. Treat the upstream function name and hash as entry clues, then also find source-count clearing, bulk frags[] copies, and custom skb aggregation.
The repair changes no RFC 9347 wire format and imposes no coordinated peer upgrade. Aggregate layout remains compatible; only the local decision to obtain private writable storage changes. Tunnel endpoints can update on separate schedules, but every endpoint that transmits through the vulnerable path must fix its own kernel. An updated peer cannot protect a sender's page.
Nor does the patch force every packet to copy. Truly private fragments that satisfy the other ESP conditions retain the in-place path. Only collections marked shared recover copy-on-write. The performance cost is therefore aligned with the ownership risk instead of being paid globally.
Any increase in copying should be interpreted honestly. If shared bytes are about to be transformed, a private copy is part of correctness. Capacity testing should establish whether the secure behavior meets service objectives and drive scaling where necessary; removing the flag to restore old throughput would reintroduce the defect.
Small kernel patches can require large proofs. One bit crosses page lifetime, aggregate semantics, and cryptographic writing. Review notes should explain why OR, condition, mask, and position are essential so a future cleanup does not delete the operation as redundant bookkeeping.
Tests and comments should lead with the invariant, using the CVE as an index: after any shared fragment is moved, the destination must continue to report shared until private storage is created. That sentence remains useful after the identifier fades and applies to future helpers.
The final virtue of the repair is locality of responsibility. The IP-TFS helper knows exactly which fragments enter the destination, so it carries their property. ESP can consume that trustworthy property without rediscovering each page's origin. Each layer maintains the facts it is best positioned to know.
6.2 Upstream versions are coordinates; the running build is the final answer
The CNA record identifies the introducing commit and several git ranges. For operational use, the upstream summary is that the implementation arrived in the 6.14 era, the 6.18 line is fixed from 6.18.36, the 7.0 line from 7.0.13, and 7.1 contains the mainline repair. Later stable point releases should inherit their line's fix.
Recheck those coordinates against the official record when acting, because stable lines continue to evolve. The report retains commit identities so reviewers can verify code beyond labels. A build with equivalent propagation has the core repair even if its package number differs; a changed version string without the property is not evidence.
Mainline and stable commits naturally have different hashes after cherry-pick or backport. Fleet tooling must not demand the literal object e9096a5a170e everywhere. It should recognize the stable or vendor commit and, ultimately, the source behavior. Map vendor advisory identifiers to the same function and invariant.
For self-built kernels, confirm that the source tree, configuration, patch set, installed image, and booted image are the same artifact. It is common to fix a build directory while a host continues booting an older EFI entry. Record the build ID, boot path, and image hash, then collect them again after restart.
If IP-TFS is modular, replacing one module outside the supported kernel package can create interface risk; if the code is built in, a module operation cannot update it. Prefer the vendor's supported complete kernel update and reboot unless it explicitly supports a corresponding live patch or module replacement.
A live patch may be feasible because the source change is small, but feasibility is not proof that all callers are redirected safely while skbs are active. Treat it as a verified bridge only when the vendor supports that implementation. Otherwise, a conventional update remains the known-good end state.
Choose a canary that represents real IP-TFS load, NIC/offload behavior, MTU, address families, and zero-copy sources. An idle standby cannot reveal copy cost or invariants, while the busiest node may unnecessarily magnify unknown regressions. Representative is more important than merely small.
Capture a baseline before the canary: throughput, CPU, soft IRQs, allocation, loss, latency, XFRM errors, application validation, and original-page integrity. Reuse the controlled traffic after updating. A resource increase can be investigated; any change to source data remains a hard failure.
Define rollback conditions separately for availability and security. A tunnel that cannot establish or a severe stability regression may justify rollback to a reviewed mitigated state. A modest copy cost does not justify returning to vulnerable code; scale capacity or reduce risky traffic while preserving isolation.
If an immediate update is impossible, stop creating IP-TFS transmit states on affected endpoints and use an assessed alternative. This sacrifices some traffic-analysis protection and may affect capacity, so security and service owners must approve it and assign an expiration date.
Forcing applications to copy into private buffers is another bridge, but it is harder to prove and can be undone by a framework optimization or message-size branch. Validate files, small messages, and failover behavior if it is used. Do not let this control become a permanent replacement for a fixed kernel.
Disabling an offload or forcing linearization might avoid the observed in-place branch on one implementation, yet side effects and coverage vary. Without source and runtime evidence, call this a likelihood reduction, not a repair. A generic switch is not supported merely because one laboratory run copied.
Sequence upgrades by evidence: assets with observed source changes first; assets with all four path facts next; images and standby nodes that can enable the path next; and builds with only possible code presence still included in final cleanup. This addresses current exposure without leaving a future configuration trap.
A version ticket closes only when the running build contains the repair, active tunnels pass both directions, shared source pages remain unchanged, and secure-path capacity meets objectives. The next chapter turns those conclusions into a repeatable laboratory procedure that needs no destructive exploit.
7 Prove the Ownership Invariant Without Running a Destructive Exploit
7.1 Begin with source proof: correct repair, correct location, no bypass implementation
Start with the source package or traceable vendor build actually used by the target. Locate iptfs_consume_frags() without assuming it matches upstream text. Record how it obtains source and destination skb_shared_info, copies fragments, updates the destination count, and clears the source count.
Assertion one: when the source has fragments, destination flags inherit source SKBFL_SHARED_FRAG through OR. If the repair is wrapped in a helper, follow it to the actual write. Preserve enough context in the review evidence to show that propagation belongs to the same transfer.
Assertion two: propagation occurs before the source gives up members. The condition must use the pre-clear fragment count. A refactored implementation can cache the count before clearing and remain equivalent, but the review should explain why that cached value describes the moved collection.
Assertion three: later initialization does not overwrite the destination result. A vendor tree may set flags while constructing a template or offload layout. Trace the value beyond the OR so a correctly placed line is not silently nullified afterward.
Assertion four: no alternate fragment-move path bypasses the helper. Search bulk copies of frags[], writes that zero source nr_frags, destination-count increments, and IP-TFS-specific helpers. Distribution performance patches and device paths are common places for an older implementation to fork.
Assertion five: both ESP address-family implementations still consume the shared result when deciding whether to copy. If a vendor moved the logic into a common helper or driver, verify branch meaning and ensure flags are not cleared before the check.
Assertion six: skb_has_shared_frag() retains its expected meaning—nonlinear data plus the shared bit. A vendor that extends flags or nonlinear layout may require a fresh proof that the backport covers the pages ESP can write.
Write the six results as an evidence table with build, file, function, and conclusion. Another reviewer can reproduce each result and compare it after the next update. A bare “contains the CVE fix” statement cannot support that audit.
Source proof now establishes what must occur. Runtime testing no longer hunts blindly for a crash; it observes one fact at four points: the source is shared, the destination inherits, ESP copies, and the original page remains unchanged.
7.2 Then run controlled tests: two page sources, two address families, three aggregate orders
Use an isolated host or virtual machine with a dedicated build, no production data, and separate network namespaces. Fix CPU placement, MTU, device features, and XFRM configuration. Record the build identity after every reboot. Test bytes should be synthetic, repeatable, and safe to publish.
Prepare the first source as a fixture file with known blocks and a pre-send hash. Use a send path that can retain page-cache fragments while another legitimate reader can inspect the original content. Confirm that the actual skb is nonlinear and marked shared instead of inferring it from the API name.
Prepare the second source as anonymous pages passed into a pipe with vmsplice(). Retain one controlled observer while another path feeds the socket. Fingerprint the pages before IP-TFS. Together, the file and pipe sources test two distinct ownership relationships.
Configure a minimal IP-TFS XFRM state and peer. First send a private buffer to validate ordinary tunnel operation, counters, policy selection, and peer plaintext. A trustworthy network baseline prevents later source changes from being blamed on broken configuration.
Observation point one is entry to iptfs_consume_frags(): source fragment count and shared bit. Use a debug build, temporary tracepoint, or reviewed BPF technique suitable for that exact kernel. Never deploy a structure-dependent probe onto an unmatched production build.
Observation point two follows transfer: destination count and flag, with the source count now zero. The fixed-kernel assertion is simple—if any moved source collection was shared, the destination is shared. A vulnerable build can serve as an isolated comparison but must never carry real traffic.
Observation point three is ESP write preparation. Confirm that a shared destination takes the copy path and, where safely observable, that page identity changes before the cipher writes. If physical identity cannot be collected safely, combine a debug assertion with the original-content hash.
Observation point four returns to the source. After ESP completes and the peer receives correct plaintext, reread the fixture file and retained pipe data byte for byte. Their hashes must remain unchanged. Ciphertext belongs only to private packet storage.
Run IPv4 and IPv6 ESP separately. The source files are parallel but distinct, and a vendor backport can repair only one. If a product provably excludes an address family at build time, document the exclusion and its build evidence explicitly.
Cover private-then-shared, shared-then-private, and several shared sources entering one destination. These orders prove OR monotonicity: once any member makes the aggregate shared, later private members cannot launder that status before a real copy occurs.
Add an empty-source kernel selftest in which the internal fixture has no actual frags but controlled flags. It must not change destination state. Safe in-kernel selftest machinery supplies this internal condition without exposing a structure-forging input path.
Vary aggregate boundaries: a source that exactly fills the output, one split across outputs, and several inner packets in one outer packet. Different consumption branches can otherwise leave a polished test covering only the easiest whole-transfer case.
Vary clone, frag-list, and linearization conditions. Even where another reason forces copying, propagation must remain correct. These controls explain why some production traffic looks safe while the build still carries the defect.
Run sustained synthetic load at realistic proportions and compare throughput, latency, CPU, memory bandwidth, and allocation failures. Separate shared and private traffic so expected copying is visible only where required. The objective is capacity planning under correct semantics.
Exercise tunnel recreation, policy changes, device reset, and failover. Each scenario keeps source-page integrity as a hard assertion; successful network recovery alone is not enough. Store input hashes, build hashes, XFRM configuration, four observation points, peer output, and source post-hashes in the result.
After testing, remove temporary keys, namespaces, fixture data, and probes. Preserve only the necessary sanitized evidence. A controlled experiment remains safe through cleanup as well as execution.
When all six source assertions and the four runtime observations pass, the result is complete: state transfer is right, the consumer takes the right action, the outside object does not change, and protocol function remains intact. The final chapter turns that proof into incident response and permanent engineering practice.
8 Close the Entire Ownership Chain, Not Merely the Missing Bit
8.1 Let evidence drive response: stop new writes, update, verify, and review
During the first hour, identify systems transmitting through IP-TFS rather than rebooting every Linux host and erasing the scene. Freeze relevant configuration changes and export active and pending XFRM states and policies with namespace, address family, peer, counters, and service owner. At the same time, collect kernel release, build ID, booted image, module hashes, vendor-advisory mapping, and the source property of iptfs_consume_frags(). An asset whose exact source is unavailable remains unverified; a release string alone cannot clear it.
Next, identify shared-page sources and source-side symptoms together. Application teams should distinguish “uses a relevant API” from “this traffic produced shared nonlinear fragments” across file sends, pipes, caches, proxies, and high-throughput frameworks. File-integrity anomalies, application checksums, pipe-consumer failures, cache corruption, and data differences tied to an IP-TFS policy should be correlated with XFRM counters and send logs. Outer packet captures remain context, not the primary detector.
If a source change matches the verified chain, isolate the transmitter and affected object, preserve build, configuration, source, and packet evidence, and avoid retransmitting the same production page. If no anomaly is visible but all path facts align, move traffic to a fixed gateway or prevent IP-TFS transmit states on the affected node, documenting the loss of traffic-shape protection, capacity effect, owner, expiration, and drift monitoring. Kernel replacement does not repair bytes already changed, so restoration and remediation proceed in parallel.
Where IP-TFS cannot be disabled, a verified application-level private copy or vendor-supported temporary kernel repair is only a bridge with stated source and branch coverage. Build deployment waves around observed anomalies, complete four-factor paths, configurations that may activate, and code-only candidates; include standby nodes and base images. Before deployment, verify the masked OR, nonzero source condition, pre-clear placement, destination-state preservation, and the enabled IPv4 or IPv6 consumers. The end state remains a supported kernel with equivalent propagation.
After updating the canary, verify boot and tunnel health, then run the shared-page fixture. Expand only when peer plaintext is correct, the original page is unchanged, the destination retains the bit, and ESP writes to private storage. If secure copying pushes CPU or memory bandwidth near the limit, reduce per-node load, add instances, or adjust scheduling. During each wave, watch XFRM errors, replay, loss, latency, soft IRQs, allocation failures, and application content validation for a representative traffic and failover cycle.
Investigate interoperability failures through policy, keying, modules, and device compatibility because the repair does not alter wire format; any rollback must return to a known mitigated state. After fleet installation, inspect the actual running hashes and remove unrebooted hosts, stale boot entries, unmanaged edges, and old base images. Restore temporary features one at a time on fixed nodes, rechecking privacy, performance, and the data invariant after each change.
Recover altered data according to its source: compare persistent files with trusted copies, decide whether message or pipe streams require replay, and rebuild caches from authoritative data. Communications should state the established condition—a Linux XFRM IP-TFS fragment transfer omitted the shared flag and could let ESP transform a page still visible outside the packet—without inflating it into universal remote code execution or minimizing it as a performance bug. Close by linking introduction, deployment, asset evidence, temporary controls, repair, validation, restoration, and stale-image removal into a chain another engineer can reproduce.
8.2 Permanent engineering: give metadata a migration rule as strong as the data's
Long-term control begins with an attribute matrix for skb fragment moves. Every helper that transfers, merges, or splits frags[] should verify sharing, checksum state, truesize, release responsibility, and destination counts rather than compare payload bytes alone. Aggregate properties also need explicit rules: if any member remains externally shared, the destination collection must retain that restriction; bits stored in the same integer do not necessarily share the same algebra.
That contract belongs in IP-TFS selftests. In addition to wire format, reassembly, and throughput, fixtures should cover file-cache pages, pipes, mixed private and shared sources, both address families, and different aggregate boundaries. “The peer received correct plaintext” and “the source page remained unchanged” must be separate assertions: one proves functional success, while the other proves that zero-copy respected ownership.
Code review should carry the same ownership questions into every performance optimization: who can still observe the data, where the first write occurs, what state forces a copy, and how that state crosses each handoff. Consumers with truly equivalent semantics should share a decision helper, but its contract must still distinguish skb clones, externally shared nonlinear pages, and device-specific writable layouts. Comments on critical flags should describe that ownership constraint rather than only a historical checksum use.
The same model can guide defect-class scanning: find functions that move fragments and clear the source count without propagating collection state, and writers that check clone state while ignoring externally shared pages. A match is only an entry point for human review. Reachability, shared input, and an actual downstream write still require contextual proof; a rule hit cannot substitute for a vulnerability conclusion.
Response speed depends on evidence retained before an incident. Asset inventory should store vendor patch provenance, build ID, IP-TFS compile state, active configuration source, and the latest invariant test in addition to a version string. A standing, non-sensitive laboratory can then use file-cache and pipe sources, an IP-TFS peer, both address families, controlled MTUs, and safe observation points to produce repeatable answers after each kernel update.
The repaired path's performance cost also belongs in capacity planning. Zero-copy does not mean never copy: when externally observed data is about to change, copying is part of correctness. Acceptance cannot isolate traffic shape, peer content, or throughput from the rest; it must confirm IP-TFS's privacy goal, correct peer plaintext, and unchanged local source storage together, or an attractive performance number may still conceal a broken ownership contract.
These changes also require cross-subsystem review. IP-TFS maintainers understand aggregation, network-core maintainers understand skb ownership, and XFRM and crypto maintainers understand the actual write; those perspectives need to meet during design. Regression tests should likewise treat negative assertions as first-class, using a stable source fingerprint while confirming that a write occurred and enough paths were covered, so CI can catch a semantic regression without a crash or attack payload.
Organizations can periodically rehearse the mapping from a CVE record to running builds by asking teams to identify affected configurations, source properties, and the verification fixture under a time limit. Backport notes should preserve repair semantics rather than only a commit hash: even as layouts change, “OR the shared bit into the destination before clearing the source fragment count” still guides equivalent repairs on old baselines and gives auditors a stable proof target.
Finally, metrics and maintenance records should preserve the complete causal chain. Tunnel success, peer checksums, and throughput can remain normal on a vulnerable build, so regression and canary work needs reverse-effect signals such as source-page hashes, copy-on-write observation, and cache-content anomalies. The defect record should also go beyond “one flag was missed” and explain how a plaintext page came from a file or pipe, entered IP-TFS, lost its restriction, was misclassified by ESP, and regained a correct handoff through the patch.
CVE-2026-53363 ultimately protects a principle larger than one packet: zero-copy may share storage, but it cannot share away responsibility. Descriptors, lifetime, and writability must cross every handoff together. When the last consumer prepares to write, it must know whether it holds a private copy or someone else's original.
Return to the “successful” send from the opening. On a fixed kernel, all views finally agree: the peer receives correct plaintext, the outer network sees valid ciphertext, and the file page or pipe remains unchanged. There is no dramatic crash—only a modest shared bit arriving on time. That quiet consistency is what secure kernel ownership looks like.
Research record
9Evidence, objects, and sources
The material below preserves the identifiers and references used in this report.
9.1Research objects
Products, actors, techniques, affected objects, and control points discussed in the report.
Linux XFRM IP-TFS shared-page fragment flag propagation failure
Function that transfers page fragment descriptors
Ownership state that determines whether a write requires copying
IP-TFS page-fragment sharing optimization
Propagate the shared-fragment flag
A shared page enters IP-TFS and is misclassified as privately writable by ESP
9.2Event chronology
- Zero-copy optimization merged
IP-TFS begins sharing page fragments from inner skbs.
- Mainline fix lands
The shared flag is ORed into the destination before the source fragment count is cleared.
- CNA record published
The Linux CNA publishes CVE-2026-53363 and its affected-version mapping.
- SOSEC review completed
Both ESP address families, stable branches, and a controlled verification plan are reviewed.
9.3Sources and material
- CVE.org: CVE-2026-53363https://www.cve.org/CVERecord?id=CVE-2026-53363
- Linux fix e9096a5a170ehttps://git.kernel.org/stable/c/e9096a5a170e7ecd6467bc2e08668ec39897cda7
- Linux 6.18 stable fix dd66f7f6https://git.kernel.org/stable/c/dd66f7f6e360ee82cd905517726f8e9091265de5
- Linux 7.0 stable fix c885d111https://git.kernel.org/stable/c/c885d111ed9f5a0a1f3cc4e87a50db6518abaa6c
- Introducing commit b96ba312e21chttps://git.kernel.org/stable/c/b96ba312e21c9b7ac1526829b9640ddc06695c0b
- RFC 9347: IP Traffic Flow Securityhttps://www.rfc-editor.org/rfc/rfc9347.html
- Linux kernel documentation: struct sk_buffhttps://docs.kernel.org/networking/skbuff.html
- Linux kernel documentation: XFRM devicehttps://docs.kernel.org/networking/xfrm_device.html
- Linux upstream: net/xfrm/xfrm_iptfs.chttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/xfrm/xfrm_iptfs.c
- Linux upstream: include/linux/skbuff.hhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/skbuff.h
- Linux upstream: IPv4 ESP outputhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/esp4.c
- Linux upstream: IPv6 ESP outputhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/esp6.c
- Linux upstream: sk_buff core implementationhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/core/skbuff.c
- Linux man-pages: vmsplice(2)https://man7.org/linux/man-pages/man2/vmsplice.2.html
- Linux man-pages: sendfile(2)https://man7.org/linux/man-pages/man2/sendfile.2.html
- MITRE CWE-668: Exposure of Resource to Wrong Spherehttps://cwe.mitre.org/data/definitions/668.html