Skip to content

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

Open
omkhar wants to merge 1 commit 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 1 commit 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.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant