[PATCH 4.15 30/53] lib: fix stall in __bitmap_parselist()
From: Greg Kroah-Hartman
Date: Tue Apr 17 2018 - 12:52:28 EST
4.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yury Norov <ynorov@xxxxxxxxxxxxxxxxxx>
commit 8351760ff5b2042039554b4948ddabaac644a976 upstream.
syzbot is catching stalls at __bitmap_parselist()
(https://syzkaller.appspot.com/bug?id=ad7e0351fbc90535558514a71cd3edc11681997a).
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.
Link: http://lkml.kernel.org/r/20180404162647.15763-1-ynorov@xxxxxxxxxxxxxxxxxx
Fixes: 0a5ce0831d04382a ("lib/bitmap.c: make bitmap_parselist() thread-safe and much faster")
Signed-off-by: Yury Norov <ynorov@xxxxxxxxxxxxxxxxxx>
Reported-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
Reported-by: syzbot <syzbot+6887cbb011c8054e8a3d@xxxxxxxxxxxxxxxxxxxxxxxxx>
Cc: Noam Camus <noamca@xxxxxxxxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
Cc: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx>
Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
lib/bitmap.c | 2 +-
lib/test_bitmap.c | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -607,7 +607,7 @@ static int __bitmap_parselist(const char
/* 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;
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -218,6 +218,10 @@ static const struct test_bitmap_parselis
{-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},
};