Skip to content

Patch kernel: backport ipv6 fraggap OOB-write fix (torvalds/linux@736b380e)#17848

Open
omkhar wants to merge 2 commits into
microsoft:3.0-devfrom
omkhar:oarasara/ipv6-fraggap-kernel-3.0
Open

Patch kernel: backport ipv6 fraggap OOB-write fix (torvalds/linux@736b380e)#17848
omkhar wants to merge 2 commits into
microsoft:3.0-devfrom
omkhar:oarasara/ipv6-fraggap-kernel-3.0

Conversation

@omkhar

@omkhar omkhar commented Jun 29, 2026

Copy link
Copy Markdown

Backport upstream fix for the IPv6 fraggap out-of-bounds write in
__ip6_append_data() (no CVE assigned upstream as of 2026-06-29).

Upstream commit: torvalds/linux@736b380
Author: Wongi Lee qw3rtyp0@gmail.com, Jungwoo Lee jwlee2217@gmail.com
Reviewed-by: Ido Schimmel idosch@nvidia.com
Signed-off-by: Jakub Kicinski kuba@kernel.org
Fixes: 773ba4fe9104 ("ipv6: avoid partial copy for zc")
LKML thread: https://lore.kernel.org/all/ajFTqRljatR17fFy@DESKTOP-19IMU7U.localdomain/

The bug

On the paged-allocation branch of __ip6_append_data() (MSG_MORE / NETIF_F_SG /
large fraglen), alloclen/pagedlen are computed as alloclen = fragheaderlen + transhdrlen; pagedlen = datalen - transhdrlen;. datalen already includes
fraggap, so when fraggap != 0 (a non-first skb carrying bytes over from the
previous skb) the linear skb area is undersized by fraggap and the fraggap copy
writes past skb->end into the trailing skb_shared_info. Introduced by
773ba4fe9104 (v6.0); became reachable once ce650a166335 (v6.5) let MSG_SPLICE_PAGES
proceed past the previously--EINVAL negative-copy case. An unprivileged user
can trigger it via a corked UDPv6 socket using MSG_SPLICE_PAGES.
Both gating
commits are present in 6.6.143.1, so Azure Linux 3.0 is affected.

The fix adds fraggap to alloclen and subtracts it from pagedlen, and removes
the now-stale MSG_SPLICE_PAGES exception in the negative-copy check.

Vulnerable behaviour reproduced on Azure Linux 3.0 6.6.143.1

Built KASAN diagnostic kernels from the spec's exact source tag
(rolling-lts/mariner-3/6.6.143.1, config matching SPECS/kernel/config):
6.6.143.1-fraggap-baseline+ (unpatched) and -fraggap-fixed+ (this patch).

An unprivileged process (corked UDPv6 + two splice/MSG_SPLICE_PAGES chunks over a
640-byte type-4 SRH at IPV6_MTU 1280) corrupts skb_shared_info. The witness is
the free-time crash
when the corrupted nr_frags/frag_list is walked on
finalize — a real KASAN report on the unmodified kernel:

general protection fault, probably for non-canonical address 0xdffffc0000000001 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
CPU: ... Comm: <unprivileged> ... 6.6.143.1-fraggap-baseline+
RIP: skb_release_data+0x3cb/0x6d0
Call Trace:
  kfree_skb_reason
  __ip6_flush_pending_frames        (and via udpv6_destroy_sock <- __x64_sys_close)
  ip6_flush_pending_frames
  udpv6_sendmsg / udp_lib_close

Unpatched: 10/10 runs crash (GPF / KASAN null-ptr-deref in skb_release_data).
Patched: 0/10 runs (alloclen enlarged by fraggap; the copy lands in-bounds;
skb_shared_info is never corrupted).

Why no copy-site KASAN: slab-out-of-bounds Write: the 8-byte overshoot lands
in-object (the trailing skb_shared_info sits between skb->end and the
kmalloc-1024 object end), which KASAN does not poison — so the witnessable signal
is the downstream free-path null-ptr-deref, confirmed by live address
instrumentation (write at skb->end+8 baseline vs -1016 in-bounds patched,
10/10 -> 0/10). Both witnesses are deterministic. Full analysis in the validation
bundle (kasan-mechanism-note.md).

LTP regression (baseline vs patched, same run)

LTP 20260130 (kirk), net.ipv6 net.ipv6_lib net.multicast on both kernels:

Baseline: 127 passed, 0 failed, 0 broken, 7 skipped
Patched: 127 passed, 0 failed, 0 broken, 7 skipped

No passed→failed transitions. Subsystem coverage proven via a kprobe on
__ip6_append_data (6187× baseline / 8088× patched).

Scope — the entangled kernel spec family

A kernel Release bump on Azure Linux 3.0 must keep the entangled spec family in
lockstep (CI Spec Entanglement Mismatch Check), so this is not a 2-file
change:

  • Patch + Release: 1 → 2 + %changelog on the specs that build the kernel FROM
    SOURCE: SPECS/kernel/kernel.spec AND SPECS/kernel-64k/kernel-64k.spec
    (patching only kernel while release-bumping kernel-64k would ship a
    fake-fixed 64k release). The patch is verbatim upstream git format-patch
    (trailers preserved), applied by the existing %autosetup -p1.
  • Release: 1 → 2 + %changelog only on the repackaging/headers siblings:
    kernel-uki, kernel-headers, kernel-signed, kernel-64k-signed,
    kernel-uki-signed.
  • Bumping kernel-headers cascades into Check Manifests, so the
    kernel-headers/kernel-cross-headers NVR is bumped in
    toolkit/resources/manifests/package/{toolchain,pkggen_core}_{x86_64,aarch64}.txt.

No kernel.signatures.json / cgmanifest / LICENSE-MAP change (those track
SourceN/licenses, unchanged; Source Signature Check (SPECS) passes without
them). 13 files total; all CI green.

Out-of-tree carry ahead of stable — justification (live PoC)

As of 2026-06-29 the fix is in torvalds/master but NOT yet in linux-6.6.y stable.
Requesting it ahead of stable because the bug has a working
local-privilege-escalation exploit
: the IPV6_FRAG_ESCAPE chain weaponizes this
exact fraggap OOB-write (corrupt skb_shared_info->nr_frags → page-UAF →
dirty-pagetable → unprivileged container/root escape, demonstrated on the
6.12/el10 sibling), and the same unprivileged trigger + OOB-write are wire-proven
on this 6.6.143.1 kernel here. It is reachable by any unprivileged user via a
plain UDPv6 socket.

Promotion: merge to 3.0-dev → publishes to 3.0 on the next cadence. CLA agreed
via the bot comment.

Checklist

  • Patch byte-identical to upstream git format-patch -1 736b380e (trailers preserved)
  • Release 1→2 across the entangled kernel spec family + toolchain manifests; CI all green
  • Unprivileged OOB-write reproduces 10/10 unpatched → 0/10 patched (free-time GPF / KASAN null-ptr-deref in skb_release_data, unmodified kernels)
  • LTP baseline-vs-patched: 127/0/0 both sides, 0 new regressions, coverage proven
  • No signatures.json / cgmanifest / LICENSE-MAP needed for a patch-add (verified)

@omkhar omkhar requested a review from a team as a code owner June 29, 2026 19:17
@omkhar

omkhar commented Jun 29, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@microsoft-github-policy-service microsoft-github-policy-service Bot added Packaging 3.0-dev PRs Destined for AzureLinux 3.0 labels Jun 29, 2026
@omkhar omkhar force-pushed the oarasara/ipv6-fraggap-kernel-3.0 branch from a10ac51 to b8d4e25 Compare June 29, 2026 19:36
…b380e)

Backport upstream torvalds/linux@736b380
("ipv6: account for fraggap on the paged allocation path"), which fixes an
out-of-bounds write in __ip6_append_data(). On the paged-allocation branch
alloclen/pagedlen are computed without accounting for fraggap, so when
fraggap != 0 the linear skb area is undersized and the carried-over bytes are
copied past skb->end into the trailing skb_shared_info. An unprivileged user
can trigger this via a corked UDPv6 socket using MSG_SPLICE_PAGES. The fix adds
fraggap to alloclen and subtracts it from pagedlen, and drops the now-stale
MSG_SPLICE_PAGES exception in the negative-copy check.

Wire-validated on Azure Linux 3.0 6.6.143.1 (KASAN build): the OOB-write
reproduced 10/10 on the unpatched kernel (write 8 bytes past skb->end) and
0/10 on the patched kernel (the linear allocation is enlarged by fraggap so
the copy lands in-bounds).

Signed-off-by: Omkhar Arasaratnam <omkhar@linkedin.com>
@omkhar omkhar force-pushed the oarasara/ipv6-fraggap-kernel-3.0 branch from b8d4e25 to a245fbc Compare June 29, 2026 19:39
@omkhar

omkhar commented Jun 29, 2026

Copy link
Copy Markdown
Author

Requesting fast-track / expedited consideration for this backport.

This fraggap OOB-write in __ip6_append_data() is reachable by any unprivileged
user
over a plain UDPv6 socket (corked + MSG_SPLICE_PAGES), and it has a working
local-privilege-escalation exploit
: the public IPV6_FRAG_ESCAPE chain weaponizes
this exact bug — corrupting skb_shared_info->nr_frags → page-UAF → dirty-pagetable →
unprivileged container/root escape (demonstrated on the 6.12/el10 sibling). The same
unprivileged trigger and OOB-write are wire-proven on this Azure Linux 3.0 6.6.143.1
kernel
in this PR (10/10 crash unpatched → 0/10 patched; free-time GPF /
KASAN: null-ptr-deref in skb_release_data).

The upstream fix (torvalds/linux@736b380e) is not yet in linux-6.6.y stable, so
AzL3 is exposed until the stable pickup propagates. Given the unprivileged-LPE
severity + live exploit, would you consider expediting this — and is fasttrack/3.0
the channel you'd prefer for it, or is 3.0-dev fine? Happy to retarget/split however
you'd like. CLA agreed (@microsoft-github-policy-service agree). All 17 CI checks are
green.

@omkhar

omkhar commented Jun 30, 2026

Copy link
Copy Markdown
Author

Maintainer's call: while the published POC is for ipv6, you may consider adding the ipv4 fix as well for completeness.

Full series here https://lore.kernel.org/all/ajFQn6yh43eDeQm9@DESKTOP-19IMU7U.localdomain/

Let me know if you'd like me to revise the spec to include both.

@rlmenge

rlmenge commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Thanks for the thorough write-up and validation work @omkhar.

On the changes themselves, SPECS-EXTENDED/kernel-ipe/kernel-ipe.spec also needs a Release bump + changelog entry to stay in lockstep with the kernel family. We don't have CI enforcement for this one yet, but it's part of the entangled set — check other recent kernel PRs for the pattern.

As for the patch, it looks like this will be picked up in 6.6.144 https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git/tree/queue-6.6/ipv6-account-for-fraggap-on-the-paged-allocation-path.patch. We're evaluating whether to take this as a spec patch or cherry-pick into the kernel source repo instead. Will follow up once we have a decision — appreciate your patience.

kernel-ipe is part of the kernel spec entanglement group but is not
covered by the CI Spec Entanglement Mismatch Check. Bump Release 1 -> 2
and add a %changelog entry to match the rest of the family for the ipv6
fraggap OOB-write fix (torvalds/linux@736b380e28d0).
@omkhar omkhar requested a review from a team as a code owner June 30, 2026 17:39
@omkhar

omkhar commented Jun 30, 2026

Copy link
Copy Markdown
Author

Thanks @rlmenge — good catch on kernel-ipe. I've pushed the Release: 1 → 2 + %changelog bump on SPECS-EXTENDED/kernel-ipe/kernel-ipe.spec to keep it in lockstep with the rest of the family (changelog worded to match the other repackaging-only siblings in this set, since kernel-ipe builds against the kernel rather than carrying the patch itself). That brings the PR to 14 files.

Totally your call on spec patch vs. cherry-pick into the kernel source repo — happy to rework it whichever way you land. And since this is queued for 6.6.144, I'm equally happy to just close this and let the 6.6.144 stable auto-upgrade carry it via the normal servicing cadence if you'd rather wait for the pickup. Whatever's least churn on your side.

The ipv4 sibling from the same series is still on offer too — say the word and I'll fold it into whichever route you choose.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the specs-extended PR to fix SPECS-EXTENDED label Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.0-dev PRs Destined for AzureLinux 3.0 Packaging specs-extended PR to fix SPECS-EXTENDED

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants