+cc Thomas in case the commit it's sat at is indicative, there does seem to be
some weirdness with MMF_MULTIPROCESS processes (i.e. CLONE_VM but !CLONE_THREAD)
resulting in possible memory corruption?
We kinda need a repro to be sure though I think...
On Mon, Feb 16, 2026 at 02:43:17PM +0000, Lorenzo Stoakes wrote:
> On Mon, Feb 16, 2026 at 03:40:21PM +0100, David Hildenbrand (Arm) wrote:
> > On 2/14/26 17:40, syzbot wrote:
> > > Hello,
> > >
> > > syzbot found the following issue on:
> > >
> > > HEAD commit: 1e83ccd5921a sched/mmcid: Don't assume CID is CPU owned on..
> > > git tree: upstream
> > > console output:
https://syzkaller.appspot.com/x/log.txt?x=1169dae6580000
> > > kernel config:
https://syzkaller.appspot.com/x/.config?x=54ae71b284dd0e13
> > > dashboard link:
https://syzkaller.appspot.com/bug?extid=6b554d491efbe066b701
> > > compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> > >
> > > Unfortunately, I don't have any reproducer for this issue yet.
We're going to need one I fear :)
vma = lock_vma_under_rcu(mm, address);
if (!vma)
goto lock_mmap; <--- didn't jump there, so is a VMA lock.
if (unlikely(access_error(error_code, vma))) {
bad_area_access_error(regs, error_code, address, NULL, vma);
count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
return;
}
fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs); <-- here
> > > handle_page_fault arch/x86/mm/fault.c:1474 [inline]
> > > exc_page_fault+0x6f/0xd0 arch/x86/mm/fault.c:1527
> > > asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:618
> >
> > This is the VM_BUG_ON_MM(hpage_collapse_test_exit(mm), mm), which checks
> >
> > atomic_read(&mm->mm_users) == 0;
Yeah, and that just shouldn't be possible, so maybe memory corruption?
The crash log indicates the system is tainted by softlock
https://syzkaller.appspot.com/text?tag=CrashLog&x=1169dae6580000 so something's
gone horribly wrong there...
(from crash log)
[ 696.104336][T16472] pgd ffff8880319b0000 mm_users 0 mm_count 2 pgtables_bytes 155648 map_count 32
VMA's still there so exit_mmap() hasn't run yet...
But hmm we injected a fault :)
[ 696.293779][T16475] FAULT_INJECTION: forcing a failure.
[ 696.293779][T16475] name fail_page_alloc, interval 1, probability 0, space 0, times 0
[ 696.332139][T16475] dump_stack_lvl+0x100/0x190
[ 696.332164][T16475] should_fail_ex.cold+0x5/0xa
[ 696.332178][T16475] ? prepare_alloc_pages+0x16d/0x5f0
[ 696.332200][T16475] should_fail_alloc_page+0xeb/0x140
[ 696.332219][T16475] prepare_alloc_pages+0x1f0/0x5f0
[ 696.332241][T16475] __alloc_frozen_pages_noprof+0x193/0x2410
[ 696.332258][T16475] ? stack_trace_save+0x8e/0xc0
[ 696.332277][T16475] ? __pfx_stack_trace_save+0x10/0x10
[ 696.332297][T16475] ? stack_depot_save_flags+0x27/0x9d0
[ 696.332315][T16475] ? __lock_acquire+0x4a5/0x2630
[ 696.332331][T16475] ? kasan_save_stack+0x3f/0x50
[ 696.332346][T16475] ? __pfx___alloc_frozen_pages_noprof+0x10/0x10
[ 696.332360][T16475] ? copy_time_ns+0xf6/0x800
[ 696.332379][T16475] ? unshare_nsproxy_namespaces+0xc3/0x1f0
[ 696.332408][T16475] ? __x64_sys_unshare+0x31/0x40
[ 696.332423][T16475] ? do_syscall_64+0x106/0xf80
[ 696.332437][T16475] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 696.332460][T16475] ? __sanitizer_cov_trace_switch+0x54/0x90
[ 696.332480][T16475] ? policy_nodemask+0xed/0x4f0
[ 696.332500][T16475] alloc_pages_mpol+0x1fb/0x550
[ 696.332519][T16475] ? __pfx_alloc_pages_mpol+0x10/0x10
[ 696.332542][T16475] alloc_pages_noprof+0x131/0x390
[ 696.332560][T16475] copy_time_ns+0x11a/0x800
So:
static struct nsproxy *create_new_namespaces(u64 flags,
struct task_struct *tsk, struct user_namespace *user_ns,
struct fs_struct *new_fs)
{
...
new_nsp->time_ns_for_children = copy_time_ns(flags, user_ns,
tsk->nsproxy->time_ns_for_children); <- -ENOMEM
if (IS_ERR(new_nsp->time_ns_for_children)) {
err = PTR_ERR(new_nsp->time_ns_for_children);
goto out_time;
}
...
out_time:
put_net(new_nsp->net_ns);
out_net:
put_cgroup_ns(new_nsp->cgroup_ns);
out_cgroup:
put_pid_ns(new_nsp->pid_ns_for_children);
out_pid:
put_ipc_ns(new_nsp->ipc_ns);
out_ipc:
put_uts_ns(new_nsp->uts_ns);
out_uts:
put_mnt_ns(new_nsp->mnt_ns);
out_ns:
kmem_cache_free(nsproxy_cachep, new_nsp);
return ERR_PTR(err);
}
So we're putting the world... maybe some of this is buggy?
[ 696.332578][T16475] ? copy_cgroup_ns+0x71/0x970
[ 696.332601][T16475] create_new_namespaces+0x48a/0xac0
So:
int unshare_nsproxy_namespaces(unsigned long unshare_flags,
struct nsproxy **new_nsp, struct cred *new_cred, struct fs_struct *new_fs)
{
...
*new_nsp = create_new_namespaces(unshare_flags, current, user_
new_fs ? new_fs : current->fs);
if (IS_ERR(*new_nsp)) {
err = PTR_ERR(*new_nsp);
goto out;
}
...
out:
return err;
}
[ 696.332626][T16475] unshare_nsproxy_namespaces+0xc3/0x1f0
[ 696.332648][T16475] ksys_unshare+0x455/0xab0
So:
int ksys_unshare(unsigned long unshare_flags)
{
...
err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
new_cred, new_fs);
if (err)
goto bad_unshare_cleanup_cred;
...
bad_unshare_cleanup_cred:
if (new_cred)
put_cred(new_cred);
bad_unshare_cleanup_fd:
if (new_fd)
put_files_struct(new_fd);
bad_unshare_cleanup_fs:
if (new_fs)
free_fs_struct(new_fs);
bad_unshare_out:
return err;
}
And again we're putting all the things... maybe something buggy here?
Perhaps this unshare is racing with something else?
OTOH, we _already_ had mm_users = 0 at this point (as per mm dump) so. Probably
something before got us into this state?
[ 696.332664][T16475] ? __pfx_ksys_unshare+0x10/0x10
[ 696.332679][T16475] ? xfd_validate_state+0x129/0x190
[ 696.332702][T16475] __x64_sys_unshare+0x31/0x40
[ 696.332717][T16475] do_syscall_64+0x106/0xf80
[ 696.332730][T16475] ? clear_bhb_loop+0x40/0x90
[ 696.332747][T16475] entry_SYSCALL_64_after_hwframe+0x77/0x7f
Also from mm dump:
flags: 00000000,840007fd
MMF_TOPDOWN | MMF_MULTIPROCESS | (core dump flags)
No MMF_VM_HUGEPAGE...
MMF_MULTIPROCESS marks this as shared between processes, as set in
copy_process() -> copy_oom_score_adj() which has a guard:
/* Skip if spawning a thread or using vfork */
if ((clone_flags & (CLONE_VM | CLONE_THREAD | CLONE_VFORK)) != CLONE_VM)
return;
Which grabs the mm in __set_oom_adj() which as per commit 44a70adec910 ("mm,
oom_adj: make sure processes sharing mm have same view of oom_score_adj")
suggests processes were cloned with CLONE_VM but not CLONE_SIGHAND (which
presumably implies !CLONE_THREAD).
Anyway it's hard to know with a repro.
Cheers, Lorenzo