syzbot is catching stalls at __bitmap_parselist() [1]. The trigger is

  unsigned long v = 0;
  bitmap_parselist("7:,", &v, BITS_PER_LONG);

which results in hitting infinite loop at

    while (a <= b) {
            off = min(b - a + 1, used_size);
            bitmap_set(maskp, a, off);
            a += group_size;
    }

due to used_size == group_size == 0.

Reported-by: Tetsuo Handa <[email protected]>
Reported-by: syzbot <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
---
 lib/bitmap.c      | 2 +-
 lib/test_bitmap.c | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index 9e498c77ed0e..a42eff7e8c48 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -607,7 +607,7 @@ static int __bitmap_parselist(const char *buf, unsigned int 
buflen,
                /* if no digit is after '-', it's wrong*/
                if (at_start && in_range)
                        return -EINVAL;
-               if (!(a <= b) || !(used_size <= group_size))
+               if (!(a <= b) || group_size == 0 || !(used_size <= group_size))
                        return -EINVAL;
                if (b >= nmaskbits)
                        return -ERANGE;
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 756f20ad03db..de16f7869fb1 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -255,6 +255,10 @@ static const struct test_bitmap_parselist 
parselist_tests[] __initconst = {
        {-EINVAL, "-1", NULL, 8, 0},
        {-EINVAL, "-0", NULL, 8, 0},
        {-EINVAL, "10-1", NULL, 8, 0},
+       {-EINVAL, "0-31:", NULL, 8, 0},
+       {-EINVAL, "0-31:0", NULL, 8, 0},
+       {-EINVAL, "0-31:0/0", NULL, 8, 0},
+       {-EINVAL, "0-31:1/0", NULL, 8, 0},
        {-EINVAL, "0-31:10/1", NULL, 8, 0},
 };
 
-- 
2.14.1

Reply via email to