high

CVE

CVE-2026-98260, CVE-2026-98256, CVE-2026-89754, CVE-2026-80775, CVE-2026-98385, CVE-2026-97941

CWE

CWE-416, CWE-362, CWE-787

Affected Surface

  • Linux kernel stable lines with the disclosed Infinity Core fixes still missing, especially `5.7+`, `6.15+`, `6.17+`, and `7.2.x` depending on subsystem
  • Linux servers, container hosts, self-hosted CI runners, and developer workstations where low-privilege code can already execute
  • Android builds that carry the affected kernel code paths
  • Kernels with vulnerable exec and signal cleanup around non-leader `execve()`
  • Kernels with the vulnerable `mm/pagewalk`, `futex`, `sched/cache`, or `SLUB` changes described below

The strongest non-duplicative Linux item from the last three days is the Infinity Core disclosure posted to oss-security on 17 October. It is not one bug. It is a short cluster of six kernel flaws spread across timer cleanup, signal delivery, page-table walking, futex private hashes, scheduler cache accounting, and SLUB partial-list handling.

That breadth matters more than the marketing name. The common thread is that several old kernel assumptions stopped holding under newer fast paths, retry paths, or lifetime changes. If you already have low-privilege code execution on a host through a malicious package, a compromised CI step, or a container escape attempt, these bugs can make that foothold much more useful.

What Infinity Core actually covers

Public disclosures and upstream fixes currently center on these six CVEs:

CVESubsystemBug shapePublicly tracked fixed stable releases
CVE-2026-98260exec / POSIX CPU timersuse-after-free after non-leader execve() failure leaves a timer node queued on the wrong task6.6.158, 6.12.112, 6.18.54, 7.2.8
CVE-2026-98256signal / POSIX timerssignal-queue corruption and use-after-free during non-leader execve() and exiting-task signal flush6.18.54, 7.2.8
CVE-2026-89754mm/pagewalkstale retry state leaks upward and makes mincore() write past its result buffer6.18.50, 7.2.4
CVE-2026-80775futexnested vfork() lets two tasks race to publish the initial private-hash ref counter6.18.47, 7.1.11, 7.2.1
CVE-2026-98385scheduler cache accountingcache-accounting state stays tied to a freed mm_struct and becomes a use-after-free7.2.9
CVE-2026-97941SLUBpartial-list and freelist return race corrupts list state and can panic the kernel7.2.7

The public technical repository tied to the disclosure includes proof-of-concept material and notes about server LPE, container escape, and Android exposure. Not every CVE has the same blast radius, but the cluster is enough to make patch lag on shared Linux hosts risky.

Why AppSec teams should care

None of these bugs gives an attacker the initial foothold. They change what a foothold can become:

malicious package, poisoned build step, or container code execution
  -> low-privilege process lands on a Linux host
  -> host kernel still carries one of the Infinity Core bugs
  -> attacker trades that foothold for root, broader container escape paths, or a kernel panic

That is why these issues matter outside the platform team. Shared runners, build agents, developer laptops, and Kubernetes nodes are exactly the places where application-layer compromise often begins with ordinary user code execution.

The timer and signal bugs both start with non-leader exec

The cleanest way to understand the cluster is to start with the two bugs that sit closest together.

CVE-2026-98260 is the timer bug. Upstream describes a non-leader thread that owns a per-thread CPU timer, calls execve(), switches TIDs in de_thread(), and later dies on an exec failure path before the timer node is cleaned up. The fixing commit moved that cleanup immediately after de_thread():

static void posixtimer_exec(struct task_struct *me)
{
#ifdef CONFIG_POSIX_TIMERS
    spin_lock_irq(&me->sighand->siglock);
    posix_cpu_timers_exit(me);
    spin_unlock_irq(&me->sighand->siglock);
    exit_itimers(me);
    flush_itimer_signals();
#endif
}

retval = de_thread(me);
if (retval)
    goto out;

posixtimer_exec(me);

That patch is worth reading because it changes the lifetime boundary instead of trying to make the later failure path smarter. The stale node is gone before exec_mmap() and friends can fail.

CVE-2026-98256 sits nearby. The signal-side bug showed that flushing task::pending too late left a window where timer signal delivery and task exit could scribble over each other. The fix does two things. First, it stops queueing task-private signals to a task that already has PF_EXITING set:

static inline bool task_can_queue_signal(struct task_struct *t, enum pid_type type)
{
    lockdep_assert_held(&t->sighand->siglock);

    if (!(t->flags & PF_EXITING))
        return true;

    return type != PIDTYPE_PID;
}

Second, it flushes tsk->pending earlier inside exit_signals() while holding the right lock, then frees the detached list after dropping the lock. That is not a cosmetic change. It redraws the point where the kernel promises “nothing new will be queued here.”

The pagewalk bug is tiny in diff size and ugly in effect

CVE-2026-89754 is the best reminder that small fixes can still describe serious breakage. The patch is only a few lines:

again:
    walk->action = ACTION_SUBTREE;
    next = pmd_addr_end(addr, end);
    if (pmd_none(*pmd)) {

and the same reset is mirrored in walk_pud_range().

Before that change, a callback could set walk->action = ACTION_AGAIN, the walk could revisit a cleared entry, and the stale retry state could bubble up into the upper-level walk. Public analysis ties that to duplicate callbacks and an out-of-bounds write in __mincore_unmapped_range(). The fix is simple because the bug is about state that survived longer than its author expected.

The futex bug is a classic one-time initialization race

CVE-2026-80775 came from code that assumed the first task touching mm->futex.phash.ref was alone. Nested vfork() broke that assumption. The fix switched the “publish once” step to a cmpxchg() pattern:

if (!mm->futex.phash.ref) {
    unsigned int __percpu *ref = alloc_percpu(unsigned int);

    if (!ref)
        return -ENOMEM;

    this_cpu_inc(*ref); /* 0 -> 1 */
    if (cmpxchg(&mm->futex.phash.ref, NULL, ref))
        free_percpu(ref);
}

That tells you almost everything you need to know. The bug was not in later futex operations. It was in the assumption that the very first ref-counter installation did not need synchronization.

The two 7.2-only fixes are about decoupling lifetime from stale ownership

The scheduler and SLUB bugs are narrower in version scope but still useful to defenders because both expose the same class of mistake: data stayed attached to an object whose lifetime was no longer stable.

For CVE-2026-98385, the scheduler fix stops embedding cache-accounting state directly inside mm_struct and instead moves it to a refcounted sched_cache_group:

struct sched_cache_group {
    struct sched_cache_time __percpu *pcpu_sched;
    raw_spinlock_t lock;
    unsigned long epoch;
    u64 nr_running_avg;
    unsigned long next_scan;
    unsigned long footprint;
    int cpu;
    refcount_t refcnt;
    struct rcu_head rcu;
};

That is a structural fix. The kernel no longer assumes that every CPU accounting path will stop touching the old mm_struct before another CPU frees it.

For CVE-2026-97941, the SLUB fix holds n->list_lock across both the freelist update and the partial-list insertion:

spin_lock_irqsave(&n->list_lock, flags);

if (!slab_update_freelist(s, slab, &old, &new, "__slab_try_return_freelist")) {
    spin_unlock_irqrestore(&n->list_lock, flags);
    return false;
}

add_partial(n, slab, ADD_TO_TAIL);
spin_unlock_irqrestore(&n->list_lock, flags);

That closes the ABA-style window where one CPU thought a slab could be returned while another CPU was in the middle of taking it off the node partial list.

What to check on real hosts

Start with the obvious scope questions:

uname -r
cat /etc/os-release

Then check whether you are on the narrower branches for the last two CVEs:

zgrep CONFIG_SCHED_CACHE /proc/config.gz 2>/dev/null || echo "kernel config not exposed here"

For container and CI hosts, treat any recent package-compromise or untrusted-code incident as more urgent if the kernel is still behind the fixed stable lines listed above. The public disclosure explicitly frames the cluster as relevant to container escape and Android LPE, not just classic multi-user Linux servers.

Response guidance

  1. Patch to a vendor build that includes the relevant backports for your branch, not just the nearest upstream version string you remember from a blog post.
  2. Reboot after patching. Several of these bugs live in core kernel lifetime paths where “package installed” is not the same as “host safe.”
  3. Prioritize self-hosted runners, build agents, Kubernetes nodes, shared bastions, and developer workstations that already process untrusted code.
  4. If you are investigating a recent supply-chain incident on Linux, assume the kernel may have been the second stage and review the host with that in mind.

The important lesson from Infinity Core is not that Linux had six unrelated bugs in one week. It is that kernel subsystems kept carrying state across task, memory, or list-lifetime transitions that no longer meant what the code thought they meant. The upstream fixes are a good map of where those assumptions broke.

From research to remediation

Check whether this pattern exists in your codebase

Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.

References