Revert "cpumask: fix checking valid cpu range".
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Sat, 15 Oct 2022 15:53:51 +0000 (00:53 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Oct 2022 17:45:17 +0000 (10:45 -0700)
This reverts commit 78e5a3399421 ("cpumask: fix checking valid cpu range").

syzbot is hitting WARN_ON_ONCE(cpu >= nr_cpumask_bits) warning at
cpu_max_bits_warn() [1], for commit 78e5a3399421 ("cpumask: fix checking
valid cpu range") is broken.  Obviously that patch hits WARN_ON_ONCE()
when e.g.  reading /proc/cpuinfo because passing "cpu + 1" instead of
"cpu" will trivially hit cpu == nr_cpumask_bits condition.

Although syzbot found this problem in linux-next.git on 2022/09/27 [2],
this problem was not fixed immediately.  As a result, that patch was
sent to linux.git before the patch author recognizes this problem, and
syzbot started failing to test changes in linux.git since 2022/10/10
[3].

Andrew Jones proposed a fix for x86 and riscv architectures [4].  But
[2] and [5] indicate that affected locations are not limited to arch
code.  More delay before we find and fix affected locations, less tested
kernel (and more difficult to bisect and fix) before release.

We should have inspected and fixed basically all cpumask users before
applying that patch.  We should not crash kernels in order to ask
existing cpumask users to update their code, even if limited to
CONFIG_DEBUG_PER_CPU_MAPS=y case.

Link: https://syzkaller.appspot.com/bug?extid=d0fd2bf0dd6da72496dd
Link: https://syzkaller.appspot.com/bug?extid=21da700f3c9f0bc40150
Link: https://syzkaller.appspot.com/bug?extid=51a652e2d24d53e75734
Link: https://lkml.kernel.org/r/20221014155845.1986223-1-ajones@ventanamicro.com
Link: https://syzkaller.appspot.com/bug?extid=4d46c43d81c3bd155060
Reported-by: Andrew Jones <ajones@ventanamicro.com>
Reported-by: syzbot+d0fd2bf0dd6da72496dd@syzkaller.appspotmail.com
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Yury Norov <yury.norov@gmail.com>
Cc: Borislav Petkov <bp@alien8.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/cpumask.h

index 2f065ad..c2aa0aa 100644 (file)
@@ -174,8 +174,9 @@ static inline unsigned int cpumask_last(const struct cpumask *srcp)
 static inline
 unsigned int cpumask_next(int n, const struct cpumask *srcp)
 {
-       /* n is a prior cpu */
-       cpumask_check(n + 1);
+       /* -1 is a legal arg here. */
+       if (n != -1)
+               cpumask_check(n);
        return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n + 1);
 }
 
@@ -188,8 +189,9 @@ unsigned int cpumask_next(int n, const struct cpumask *srcp)
  */
 static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp)
 {
-       /* n is a prior cpu */
-       cpumask_check(n + 1);
+       /* -1 is a legal arg here. */
+       if (n != -1)
+               cpumask_check(n);
        return find_next_zero_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1);
 }
 
@@ -229,8 +231,9 @@ static inline
 unsigned int cpumask_next_and(int n, const struct cpumask *src1p,
                     const struct cpumask *src2p)
 {
-       /* n is a prior cpu */
-       cpumask_check(n + 1);
+       /* -1 is a legal arg here. */
+       if (n != -1)
+               cpumask_check(n);
        return find_next_and_bit(cpumask_bits(src1p), cpumask_bits(src2p),
                nr_cpumask_bits, n + 1);
 }
@@ -260,8 +263,8 @@ static inline
 unsigned int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap)
 {
        cpumask_check(start);
-       /* n is a prior cpu */
-       cpumask_check(n + 1);
+       if (n != -1)
+               cpumask_check(n);
 
        /*
         * Return the first available CPU when wrapping, or when starting before cpu0,