[Deepin-Kernel-SIG] [linux 6.18-y] Fix CVE-2026-46300#1739
Conversation
…sfer helpers
maillist inclusion
category: bugfix
CVE: CVE-2026-46300
Two frag-transfer helpers (__pskb_copy_fclone() and skb_shift()) fail
to propagate the SKBFL_SHARED_FRAG bit in skb_shinfo()->flags when
moving frags from source to destination. __pskb_copy_fclone() defers
the rest of the shinfo metadata to skb_copy_header() after copying
frag descriptors, but that helper only carries over gso_{size,segs,
type} and never touches skb_shinfo()->flags; skb_shift() moves frag
descriptors directly and leaves flags untouched. As a result, the
destination skb keeps a reference to the same externally-owned or
page-cache-backed pages while reporting skb_has_shared_frag() as
false.
The mismatch is harmful in any in-place writer that uses
skb_has_shared_frag() to decide whether shared pages must be detoured
through skb_cow_data(). ESP input is one such writer (esp4.c,
esp6.c), and a single nft 'dup to <local>' rule -- or any other
nf_dup_ipv4() / xt_TEE caller -- is enough to land a pskb_copy()'d
skb in esp_input() with the marker stripped, letting an unprivileged
user write into the page cache of a root-owned read-only file via
authencesn-ESN stray writes.
Set SKBFL_SHARED_FRAG on the destination whenever frag descriptors
were actually moved from the source. skb_copy() and skb_copy_expand()
share skb_copy_header() too but linearize all paged data into freshly
allocated head storage and emerge with nr_frags == 0, so
skb_has_shared_frag() returns false on its own; they need no change.
The same omission exists in skb_gro_receive() and skb_gro_receive_list().
The former moves the incoming skb's frag descriptors into the
accumulator's last sub-skb via two paths (a direct frag-move loop and
the head_frag + memcpy path); the latter chains the incoming skb whole
onto p's frag_list. Downstream skb_segment() reads only
skb_shinfo(p)->flags, and skb_segment_list() reuses each sub-skb's
shinfo as the nskb -- both p and lp must carry the marker.
The same omission also exists in tcp_clone_payload(), which builds an
MTU probe skb by moving frag descriptors from skbs on sk_write_queue
into a freshly allocated nskb. The helper falls into the same family
and warrants the same fix for consistency; no TCP TX-side in-place
writer is currently known to reach a user page through this gap, but
a future consumer depending on the marker would regress silently.
Fixes: cef401d ("net: fix possible wrong checksum generation")
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
Suggested-by: Sultan Alsawaf <sultan@kerneltoast.com>
Suggested-by: Ben Hutchings <ben@decadent.org.uk>
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Link: https://github.com/v12-security/pocs/tree/main/fragnesia
Link: https://x.com/v12sec/status/2054491454064746629
Link: https://lists.openwall.net/netdev/2026/05/13/79
Link: https://lore.kernel.org/all/20260513041635.1289541-1-vakzz@zellic.io/
Link: https://lore.kernel.org/all/agRfuVOeMI5pbHhY@v4bel/
[ add fix from
https://lore.kernel.org/stable/20260515164121.2608076-1-aaron1esau@gmail.com ]
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
(cherry picked from commit 6dfedcb)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
netdev inclusion category: bugfix CVE: CVE-2026-46300 skb_try_coalesce() can attach paged frags from @from to @to. If @from has SKBFL_SHARED_FRAG set, the resulting @to skb can contain the same externally-owned or page-cache-backed frags, but the shared-frag marker is currently lost. That breaks the invariant relied on by later in-place writers. In particular, ESP input checks skb_has_shared_frag() before deciding whether an uncloned nonlinear skb can skip skb_cow_data(). If TCP receive coalescing has moved shared frags into an unmarked skb, ESP can see skb_has_shared_frag() as false and decrypt in place over page-cache backed frags. Propagate SKBFL_SHARED_FRAG when skb_try_coalesce() transfers paged frags. The tailroom copy path does not need the marker because it copies bytes into @to's linear data rather than transferring frag descriptors. Fixes: cef401d ("net: fix possible wrong checksum generation") Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags") Signed-off-by: William Bowling <vakzz@zellic.io> Reviewed-by: Eric Dumazet <edumazet@google.com> Tested-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20260513041635.1289541-1-vakzz@zellic.io Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit f84eca5817390257cef78013d0112481c503b4a3) Signed-off-by: Wentao Guan <guanwentao@uniontech.com> (cherry picked from commit f786284) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Reviewer's guide (collapsed on small PRs)Reviewer's GuidePropagates SKBFL_SHARED_FRAG flags correctly when segmenting and coalescing sk_buffs to ensure shared fragment state is preserved across newly created skbs, addressing CVE-2026-46300. Flow diagram for SKBFL_SHARED_FRAG propagation in skb_segment and skb_try_coalesceflowchart TD
A[skb_segment] --> B[Create nskb]
B --> C[Copy header data from head_skb]
C --> D["Set nskb->flags |= (head_skb->flags | frag_skb->flags) & SKBFL_SHARED_FRAG"]
D --> E[Walk list_skb]
E --> F["Update frag_skb from list_skb"]
F --> G["Set nskb->flags |= frag_skb->flags & SKBFL_SHARED_FRAG"]
H[skb_try_coalesce] --> I[Copy frags from from_shinfo to to_shinfo]
I --> J[Update to_shinfo->nr_frags]
J --> K[[from_shinfo->nr_frags > 0]]
K -->|yes| L["Set to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG"]
K -->|no| M[Skip flag update]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Avenger-285714 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
skb_segment,skb_shinfo(nskb)->flagsis now updated fromfrag_skbin two different places; consider centralizing this propagation logic to a single, clearly-scoped block to avoid redundancy and reduce the chance of future divergence. - The new use of
skb_shinfo(frag_skb)->flagsinskb_segmentassumesfrag_skbis always valid at that point; if there are paths wherefrag_skbcan be NULL or uninitialized, it would be safer to guard the access or ensure its initialization is obvious at the call sites.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `skb_segment`, `skb_shinfo(nskb)->flags` is now updated from `frag_skb` in two different places; consider centralizing this propagation logic to a single, clearly-scoped block to avoid redundancy and reduce the chance of future divergence.
- The new use of `skb_shinfo(frag_skb)->flags` in `skb_segment` assumes `frag_skb` is always valid at that point; if there are paths where `frag_skb` can be NULL or uninitialized, it would be safer to guard the access or ensure its initialization is obvious at the call sites.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect propagation of SKBFL_SHARED_FRAG when sk_buffs are segmented (skb_segment) and when fragment data is coalesced (skb_try_coalesce), addressing CVE-2026-46300 related to shared-fragment handling.
Changes:
- Propagate
SKBFL_SHARED_FRAGfrom both the head skb and the current fragment-owning skb when creating new segments inskb_segment(). - Ensure
SKBFL_SHARED_FRAGis preserved whenskb_try_coalesce()merges fragment arrays fromfromintoto.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| nfrags = skb_shinfo(list_skb)->nr_frags; | ||
| frag = skb_shinfo(list_skb)->frags; | ||
| frag_skb = list_skb; | ||
| skb_shinfo(nskb)->flags |= skb_shinfo(frag_skb)->flags & SKBFL_SHARED_FRAG; |
Summary by Sourcery
Propagate shared fragment flags correctly when segmenting and coalescing sk_buffs to address incorrect handling of shared frags.
Bug Fixes: