From: Yury Norov <ynorov@nvidia.com>
To: Farhad Alemi <farhad.alemi@berkeley.edu>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Yury Norov <yury.norov@gmail.com>,
Waiman Long <longman@redhat.com>,
David Hildenbrand <david@kernel.org>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
cgroups@vger.kernel.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org
Subject: Re: [BUG] lib/bitmap: divide error in bitmap_fold() when sz argument is 0
Date: Thu, 28 May 2026 15:07:35 -0400 [thread overview]
Message-ID: <ahiSd4NoTdrYs579@yury> (raw)
In-Reply-To: <CA+0ovCgxbZkXa+OU8w3s84R3KNPNxxRfmsNR-udh+afQBbGNmw@mail.gmail.com>
Hi Farhad,
Thanks for the report. Submitted the fix and added you in CC.
Thanks,
Yury
On Thu, May 28, 2026 at 11:25:36AM -0700, Farhad Alemi wrote:
> Hello,
>
> I am reporting a divide-by-zero crash in bitmap_fold() found by syzkaller.
>
> Summary:
> bitmap_fold() at lib/bitmap.c divides by its `sz` parameter without
> guarding sz != 0:
>
> void bitmap_fold(unsigned long *dst, const unsigned long *orig,
> unsigned int sz, unsigned int nbits)
> {
> ...
> for_each_set_bit(oldbit, orig, nbits)
> set_bit(oldbit % sz, dst);
> }
>
> The call chain in the observed crash is:
>
> mpol_relative_nodemask() mm/mempolicy.c
> nodes_fold(tmp, *orig, nodes_weight(*rel))
> __nodes_fold() include/linux/nodemask.h
> bitmap_fold(dstp->bits, origp->bits, sz, nbits)
> bitmap_fold() lib/bitmap.c
>
> When `nodes_weight(*rel)` is 0 (i.e. the relative-nodes mask is empty),
> the `sz` argument passed to bitmap_fold() is 0, and the
> `oldbit % sz` expression executes a divl by zero.
>
> Observed on:
> - Linux v6.18.32-dirty (where the bug was originally found), x86_64,
> QEMU Q35
> - KASAN enabled; panic_on_warn set
> - The only local dirty file in my tree is drivers/tty/serial/serial_core.c,
> containing a local ttyS0 console guard for the fuzzing harness. It is
> unrelated to lib/bitmap, mm/mempolicy, or kernel/cgroup/cpuset.
> - The crash fires in a cpu-hotplug kernel thread (Comm: cpuhp/1, PID 21)
> reached via sched_cpu_deactivate -> cpuset_handle_hotplug ->
> cpuset_update_tasks_nodemask -> mpol_rebind_mm -> mpol_rebind_policy
> -> mpol_rebind_nodemask -> mpol_relative_nodemask -> __nodes_fold ->
> bitmap_fold.
> - Source inspection of linus/master at commit e8c2f9fdadee
> (v7.1-rc4-754-ge8c2f9fdadee) shows the buggy structure is unchanged:
> bitmap_fold() at lib/bitmap.c:718 still computes `oldbit % sz` with
> no sz != 0 guard; __nodes_fold() at include/linux/nodemask.h:365
> still forwards its sz argument; mpol_relative_nodemask() at
> mm/mempolicy.c:370 still calls nodes_fold(tmp, *orig,
> nodes_weight(*rel)). I have not re-run a reproducer against
> e8c2f9fdadee as no standalone reproducer is available yet.
>
> Impact:
> A divide-by-zero in a cpu-hotplug kernel thread context kills the
> kernel:
>
> Oops: divide error: 0000 [#1] SMP KASAN NOPTI
> CPU: 1 UID: 0 PID: 21 Comm: cpuhp/1 Not tainted 6.18.32-dirty #1 PREEMPT(full)
> RIP: 0010:bitmap_fold+0x5e/0xb0 lib/bitmap.c:713
>
> The crash report's code disassembly pins the trapping instruction to
> `divl 0x4(%rsp)` (bytes `f7 74 24 04`) with %edx pre-zeroed by the
> preceding `xor %edx,%edx` -- i.e. a 32-bit unsigned divide by the
> on-stack `sz` value.
>
> Relevant stack:
>
> bitmap_fold+0x5e/0xb0 lib/bitmap.c:713
> __nodes_fold include/linux/nodemask.h:369 [inline]
> mpol_relative_nodemask mm/mempolicy.c:372 [inline]
> mpol_rebind_nodemask+0x1e9/0x2d0 mm/mempolicy.c:508
> mpol_rebind_policy mm/mempolicy.c:542 [inline]
> mpol_rebind_mm+0x3ab/0x680 mm/mempolicy.c:569
> cpuset_update_tasks_nodemask+0x22e/0x340 kernel/cgroup/cpuset.c:2777
> hotplug_update_tasks kernel/cgroup/cpuset.c:3882 [inline]
> cpuset_hotplug_update_tasks kernel/cgroup/cpuset.c:3985 [inline]
> cpuset_handle_hotplug+0xe52/0x1200 kernel/cgroup/cpuset.c:4089
> cpuset_cpu_inactive kernel/sched/core.c:8377 [inline]
> sched_cpu_deactivate+0x497/0x600 kernel/sched/core.c:8493
> cpuhp_invoke_callback+0x44a/0x860 kernel/cpu.c:195
> cpuhp_thread_fun+0x40f/0x870 kernel/cpu.c:1105
> smpboot_thread_fn+0x546/0xa50 kernel/smpboot.c:160
> kthread+0x73e/0x8c0 kernel/kthread.c:432
>
> Expected behavior:
> Either bitmap_fold() should guard against sz == 0 (return early or
> WARN+return), or the callers in the nodes_fold / mpol_relative_nodemask
> chain should not pass a zero `sz` (e.g. short-circuit the rebind when
> the relative nodemask is empty).
>
> Reproducer:
> A standalone .syz or C reproducer was not produced for this seed; the
> crash fired during broader cpu/cgroup/mempolicy fuzzing. The console
> report is attached as crash-report.txt.
>
> Novelty check:
> I searched the syzbot dashboard's upstream open, fixed, stable, and
> invalid (per-subsystem mempolicy/mm/cgroups) namespaces, the Android
> dashboard, and the marc.info linux-mm and linux-kernel archives, for
> "bitmap_fold", "mpol_rebind_nodemask" + "divide error", "__nodes_fold"
> + "BUG"/"Oops", and "cpuset_handle_hotplug" + "BUG". I did not find an
> exact match. The recent Jinjiang Tu series (mainline commit
> 3d702678f57e, "mm/mempolicy: fix mpol_rebind_nodemask() for
> MPOL_F_NUMA_BALANCING") is a sibling fix in the same function but
> addresses wrong-rebind logic under NUMA balancing, not the
> divide-by-zero in bitmap_fold().
>
> I appreciate your time and consideration, and I'm grateful for your
> work on this subsystem. I'd be glad to test any candidate patches.
>
> Regards,
> Oops: divide error: 0000 [#1] SMP KASAN NOPTI
> CPU: 1 UID: 0 PID: 21 Comm: cpuhp/1 Not tainted 6.18.32-dirty #1 PREEMPT(full)
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> RIP: 0010:bitmap_fold+0x5e/0xb0 lib/bitmap.c:713
> Code: 31 f6 e8 a5 4e 20 fe 41 89 dc 44 89 ea 4c 89 f7 4c 89 e6 e8 84 f2 01 00 49 89 c5 44 39 eb 76 2d e8 f7 fc b9 fd 44 89 e8 31 d2 <f7> 74 24 04 89 d5 89 d0 c1 e8 06 49 8d 3c c7 be 08 00 00 00 e8 39
> RSP: 0018:ffffc9000016f520 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: 0000000000000040 RCX: ffff8881026a0000
> RDX: 0000000000000000 RSI: 0000000000000040 RDI: ffff888126f6f218
> RBP: ffffc9000016f630 R08: ffffc9000016f5a7 R09: 0000000000000000
> R10: ffffc9000016f5a0 R11: fffff5200002deb5 R12: 0000000000000040
> R13: 0000000000000000 R14: ffff888126f6f218 R15: ffffc9000016f5a0
> FS: 0000000000000000(0000) GS:ffff8882abcc4000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fcd8c9c6fe8 CR3: 0000000192758000 CR4: 0000000000750ef0
> PKRU: 55555554
> Call Trace:
> <TASK>
> __nodes_fold include/linux/nodemask.h:369 [inline]
> mpol_relative_nodemask mm/mempolicy.c:372 [inline]
> mpol_rebind_nodemask+0x1e9/0x2d0 mm/mempolicy.c:508
> mpol_rebind_policy mm/mempolicy.c:542 [inline]
> mpol_rebind_mm+0x3ab/0x680 mm/mempolicy.c:569
> cpuset_update_tasks_nodemask+0x22e/0x340 kernel/cgroup/cpuset.c:2777
> hotplug_update_tasks kernel/cgroup/cpuset.c:3882 [inline]
> cpuset_hotplug_update_tasks kernel/cgroup/cpuset.c:3985 [inline]
> cpuset_handle_hotplug+0xe52/0x1200 kernel/cgroup/cpuset.c:4089
> cpuset_cpu_inactive kernel/sched/core.c:8377 [inline]
> sched_cpu_deactivate+0x497/0x600 kernel/sched/core.c:8493
> cpuhp_invoke_callback+0x44a/0x860 kernel/cpu.c:195
> cpuhp_thread_fun+0x40f/0x870 kernel/cpu.c:1105
> smpboot_thread_fn+0x546/0xa50 kernel/smpboot.c:160
> kthread+0x73e/0x8c0 kernel/kthread.c:432
> ret_from_fork+0x4b4/0xa30 arch/x86/kernel/process.c:158
> ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
> </TASK>
> Modules linked in:
> ---[ end trace 0000000000000000 ]---
> RIP: 0010:bitmap_fold+0x5e/0xb0 lib/bitmap.c:713
> Code: 31 f6 e8 a5 4e 20 fe 41 89 dc 44 89 ea 4c 89 f7 4c 89 e6 e8 84 f2 01 00 49 89 c5 44 39 eb 76 2d e8 f7 fc b9 fd 44 89 e8 31 d2 <f7> 74 24 04 89 d5 89 d0 c1 e8 06 49 8d 3c c7 be 08 00 00 00 e8 39
> RSP: 0018:ffffc9000016f520 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: 0000000000000040 RCX: ffff8881026a0000
> RDX: 0000000000000000 RSI: 0000000000000040 RDI: ffff888126f6f218
> RBP: ffffc9000016f630 R08: ffffc9000016f5a7 R09: 0000000000000000
> R10: ffffc9000016f5a0 R11: fffff5200002deb5 R12: 0000000000000040
> R13: 0000000000000000 R14: ffff888126f6f218 R15: ffffc9000016f5a0
> FS: 0000000000000000(0000) GS:ffff8882abcc4000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fcd8c9c6fe8 CR3: 0000000192758000 CR4: 0000000000750ef0
> PKRU: 55555554
> ----------------
> Code disassembly (best guess):
> 0: 31 f6 xor %esi,%esi
> 2: e8 a5 4e 20 fe call 0xfe204eac
> 7: 41 89 dc mov %ebx,%r12d
> a: 44 89 ea mov %r13d,%edx
> d: 4c 89 f7 mov %r14,%rdi
> 10: 4c 89 e6 mov %r12,%rsi
> 13: e8 84 f2 01 00 call 0x1f29c
> 18: 49 89 c5 mov %rax,%r13
> 1b: 44 39 eb cmp %r13d,%ebx
> 1e: 76 2d jbe 0x4d
> 20: e8 f7 fc b9 fd call 0xfdb9fd1c
> 25: 44 89 e8 mov %r13d,%eax
> 28: 31 d2 xor %edx,%edx
> * 2a: f7 74 24 04 divl 0x4(%rsp) <-- trapping instruction
> 2e: 89 d5 mov %edx,%ebp
> 30: 89 d0 mov %edx,%eax
> 32: c1 e8 06 shr $0x6,%eax
> 35: 49 8d 3c c7 lea (%r15,%rax,8),%rdi
> 39: be 08 00 00 00 mov $0x8,%esi
> 3e: e8 .byte 0xe8
> 3f: 39 .byte 0x39
>
> <<<<<<<<<<<<<<< tail report >>>>>>>>>>>>>>>
>
prev parent reply other threads:[~2026-05-28 19:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-28 18:25 [BUG] lib/bitmap: divide error in bitmap_fold() when sz argument is 0 Farhad Alemi
2026-05-28 19:07 ` Yury Norov [this message]
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=ahiSd4NoTdrYs579@yury \
--to=ynorov@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=cgroups@vger.kernel.org \
--cc=david@kernel.org \
--cc=farhad.alemi@berkeley.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux@rasmusvillemoes.dk \
--cc=longman@redhat.com \
--cc=yury.norov@gmail.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.