From: Thomas Gleixner <tglx@linutronix.de>
To: Rik van Riel <riel@surriel.com>, linux-kernel@vger.kernel.org
Cc: kernel-team@meta.com, Rik van Riel <riel@surriel.com>,
Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>
Subject: Re: [PATCH v3] sched/mmcid: fix OOB clear_bit when CID is MM_CID_UNSET in fixup path
Date: Fri, 19 Jun 2026 21:40:49 +0200 [thread overview]
Message-ID: <87zf0qb9oe.ffs@fw13> (raw)
In-Reply-To: <20260616203818.1516263-1-riel@surriel.com>
On Tue, Jun 16 2026 at 16:38, Rik van Riel wrote:
> In mm_cid_fixup_cpus_to_tasks(), when rq->curr has the target mm and
> mm_cid.active is set, the CID is checked with cid_in_transit() before
> setting the transition bit. In per-CPU mode a newly forked or exec'd
> task can be running with mm_cid.cid == MM_CID_UNSET because CIDs are
> assigned lazily on schedule-in. With cid_in_transit() the guard passes
> for MM_CID_UNSET (no transit bit), converts it to MM_CID_UNSET |
> MM_CID_TRANSIT and stores it back; later mm_cid_schedout() feeds this
> to clear_bit() with MM_CID_UNSET as the bit number, triggering an
> out-of-bounds write.
>
> Symptoms: this is genuine memory corruption, but a bounded out-of-bounds
> write, not an arbitrary one. MM_CID_UNSET is the fixed sentinel BIT(31),
> so once the bad value reaches mm_cid_schedout() the cid_from_transit_cid()
> strip leaves MM_CID_UNSET, which fails the "cid < max_cids" convergence
> test and falls into mm_drop_cid() -> clear_bit(MM_CID_UNSET,
> mm_cidmask(mm)). The cid bitmap is embedded in the mm_struct slab object
> (after cpu_bitmap and mm_cpus_allowed) and is only num_possible_cpus()
> bits wide, so clearing bit 31 is a deterministic OOB bit-clear at a
> fixed offset of 2^31 / 8 == 256 MiB past the bitmap base. The address is
> not attacker-influenced (fixed sentinel -> fixed offset) and the op only
> clears a single bit; what sits 256 MiB further along the direct map is
> whatever kernel object happens to live there, so this corrupts one bit of
> unpredictable kernel memory -- it is not an arbitrary-address or
> arbitrary-value write.
>
> It triggers only in per-CPU CID mode, when a CPU is running an active
> task of the target mm whose cid is still MM_CID_UNSET -- the
> fork()/execve() window before that task's next schedule-in assigns it a
> real CID -- and a per-CPU -> per-task fixup walks over it (the mode
> fallback driven by a thread exit, sched_mm_cid_exit(), or by the deferred
> max_cids recompute in mm_cid_work_fn()).
>
> In practice syzkaller surfaced it as a KASAN use-after-free reported in
> __schedule -> mm_cid_switch_to, where the offending clear_bit() is inlined
> via mm_cid_schedout() -> mm_drop_cid().
>
> Guard the transition-bit assignment against MM_CID_UNSET, in addition to
> the existing cid_in_transit() check, so the bit is only set on a genuine
> task-owned CID. A CPU-owned (MM_CID_ONCPU) CID of a running active task
> is handled by the cid_on_cpu(pcp->cid) branch above and never reaches
> this path, so excluding MM_CID_UNSET (and the already-transitioning case)
> is sufficient.
Duh. Now that you explained it it's obvious. Thanks for tracking this
nasty down!
next prev parent reply other threads:[~2026-06-19 19:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 20:38 [PATCH v3] sched/mmcid: fix OOB clear_bit when CID is MM_CID_UNSET in fixup path Rik van Riel
2026-06-16 21:40 ` Mathieu Desnoyers
2026-06-19 19:40 ` Thomas Gleixner [this message]
2026-06-19 19:50 ` [tip: core/urgent] sched/mmcid: Fix " tip-bot2 for Rik van Riel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zf0qb9oe.ffs@fw13 \
--to=tglx@linutronix.de \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=kernel-team@meta.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=riel@surriel.com \
--cc=rostedt@goodmis.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.