All posts

CVE-2026-98432: Ubuntu has had the fix for a week, and no released LTS kernel ships it

TL;DR

15 days public · 0 released LTS kernels fixed

A remote TCP bug scored 9.8 went public on 15 October with its fix. Ubuntu signed fixed kernels for 26.04, 24.04 and 22.04 on 23 October, but they sit in -proposed: every released LTS kernel is still vulnerable, and apt upgrade will not fix it. To fix it now, install the four kernel packages for your release from -proposed and reboot. Until you can reboot, drop incoming TCP that carries IPv4 options with one nft rule. Both are below, ready to copy.

Contents
  1. A week between the fix and you
  2. Which kernel has the fix
  3. The bug
  4. The changelog does not say CVE
  5. Why -proposed and not just apt upgrade
  6. Until you can reboot
  7. What MPTCP has to do with it
  8. What to do now
  9. Sources

CVE-2026-98432 is a remote use-after-free in the Linux IPv4 TCP handshake, scored 9.8, reachable with no login. It went public on 15 October together with its fix. Ubuntu signed fixed kernels for 26.04, 24.04 and 22.04 on 23 October. Today, no released Ubuntu LTS kernel carries that fix: it sits in -proposed, and the changelogs do not mention the CVE.

If you run an Ubuntu LTS release and anything on the box listens on TCP, this is for you: how to take the fixed kernel now, and how to block the trigger with one line until you reboot.

A week between the fix and you

DateWhat happened
15 OctCVE published with the upstream fix commits
cve.org record
20 OctFix lands in the upstream stable batch Ubuntu picks up
7.0.0-43 changelog
23 OctUbuntu signs fixed kernels for 26.04, 24.04 and 22.04
changelog sign-off lines
26 Oct24.04 and 22.04 fixed kernels published to -proposed
Launchpad publishing history
28 Oct26.04 fixed kernel published to -proposed
Launchpad publishing history
29 OctUbuntu's CVE page appears, priority High
ubuntu.com tracker
30 OctEvery released LTS kernel still vulnerable
archive indexes for -updates and -security

Nobody is sitting on the fix. Ubuntu releases kernels on the SRU cycle: a whole kernel is built, tested in -proposed for a few weeks, then copied to -updates and -security. A single fix does not jump the queue unless Canonical issues an emergency respin, and so far it has not. The fixed kernel is public, signed and installable; it is just not where apt upgrade looks.

Which kernel has the fix

The same holds on every supported LTS release: the released kernels are vulnerable, and the fixed one is waiting in -proposed.

Ubuntu releaseReleased kernelIn -proposed
26.04 resolute 7.0.0-42
vulnerable
7.0.0-43
fixed
24.04 noble 6.8.0-147
vulnerable
6.8.0-149
fixed
22.04 jammy 5.15.0-202
vulnerable
5.15.0-203
fixed

Released kernel is what -updates and -security carry; unattended-upgrades installs from -security. Ubuntu's CVE page rates it High and lists each release as "vulnerable, work in progress" in exactly these -proposed versions. HWE kernels follow their own uploads and are not in this table.

The rest of this is how to get it, and what to do until you can reboot.

The bug

When a SYN arrives carrying IPv4 options, the kernel keeps those options on the request socket. tcp_v4_syn_recv_sock() hands them to the child socket without copying. A retransmitted SYN processed on another CPU can still be building a SYN-ACK from the same options while the child is freed with a plain kfree(). The fix frees them after an RCU grace period. Upstream it is in 7.2.10 and 7.3.

It lives in net/ipv4/af_inet.c and net/ipv4/tcp_ipv4.c. That is core TCP: there is no module to blacklist.

The changelog does not say CVE

We searched the 7.0.0-43 changelog for the CVE number and found nothing. The fix is there anyway, under its upstream commit title, inside the batch Resolute update: upstream stable patchset 2026-10-20:

curl -s https://changelogs.ubuntu.com/changelogs/pool/main/l/linux/linux_7.0.0-43.43/changelog \
  | awk '/^linux \(7.0.0-43.43\)/{f=1} /^linux \(7.0.0-42.42\)/{exit} f' \
  | grep 'ireq_opt'
    - ipv4: free inet_opt and ireq_opt after an RCU grace period

Ubuntu pulled the patch in with a stable batch before the CVE number was assigned. Search the changelog for the fix's title, not the CVE ID. The title is in the CVE record.

Why -proposed and not just apt upgrade

Ubuntu kernels move on the SRU cycle (Stable Release Update): built, placed in -proposed, tested for a few weeks, then copied to -updates and -security. A fix can sit finished in -proposed for weeks. Turning -proposed on for the whole system is the wrong answer: it carries every package in testing, not only the kernel. Take the four kernel packages and switch it off again.

sudo add-apt-repository -p proposed
sudo apt install linux-image-7.0.0-43-generic linux-modules-7.0.0-43-generic \
  linux-headers-7.0.0-43-generic linux-headers-7.0.0-43
sudo add-apt-repository -r -p proposed
dkms status | grep 7.0.0-43

Three things that bite:

  • Do not add -t resolute-proposed to the install. It raises the whole pocket's priority for that command, and dependencies come from -proposed too.
  • Check DKMS before rebooting. If the NVIDIA driver did not build for the new kernel, you reboot into a machine without its GPU. Every out-of-tree module has to say installed for 7.0.0-43.
  • Check /boot. On a 1 GB /boot with two kernels installed, a third leaves almost nothing. Purge the oldest kernel first, keep the running one as the GRUB fallback.

On 24.04 and 22.04 it is the same four packages with that release's version: 6.8.0-149 on noble, 5.15.0-203 on jammy.

The linux-generic metapackage stays on 7.0.0-42 and catches up on its own when 7.0.0-43 reaches -updates.

Until you can reboot

The trigger is a TCP SYN with IPv4 options. Legitimate traffic does not send them. Drop them at the front of the input path:

sudo nft 'add table inet cve; add chain inet cve in {type filter hook input priority -300;}; add rule inet cve in ip hdrlength gt 5 meta l4proto tcp drop'

Check the rule before you load it: sudo nft -c with the same quoted text parses it without changing anything. We wrote this rule from the bug's trigger and have not yet run it against the exploit; an independent write-up tested an equivalent rule and saw a SYN with a Record Route option dropped while plain SYNs connected.

ip hdrlength gt 5 matches any IPv4 header longer than the 20-byte minimum, which is exactly a header with options. Limiting it to TCP keeps IGMP working, because IGMP uses the Router Alert option. It lasts until reboot; remove it with sudo nft delete table inet cve.

Two caveats. If the box uses CIPSO labelling (SELinux or Smack NetLabel), IP options are normal traffic there, so do not add this rule. If the box routes traffic for others, use the input hook as above, not prerouting, or forwarded packets with options get dropped too.

What MPTCP has to do with it

The demonstrated exploit targets a server with a Multipath TCP listener, and Go 1.24 and later open MPTCP listeners by default. So net.mptcp.enabled = 0 is going around as the fix. Disabling MPTCP blocks the published exploit, not the bug, which is in plain IPv4 TCP. The Go Security Team's notice says so too: the bug is not specific to MPTCP, and relying on MPTCP being off assumes every viable exploit needs it. The sysctl also does not close listeners that are already open; ss -lnM lists them. Only a patched kernel fixes it.

IPv6 is not affected by the main race, because tcp_v6_syn_recv_sock() copies the options.

What to do now

  1. Exposed and can reboot: install the four kernel packages for your release from -proposed, check dkms status, reboot, and confirm uname -r shows the fixed version.
  2. Cannot reboot yet: load the nft rule now, and plan the reboot.
  3. Afterwards: watch Ubuntu's CVE page. When it says "released", the fixed kernel is in -security and the normal apt upgrade path takes over again.

Sources

Jan Kozák and Claude