diff options
author | Yury Norov <[email protected]> | 2018-04-05 16:18:25 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2018-04-05 21:36:21 -0700 |
commit | 8351760ff5b2042039554b4948ddabaac644a976 (patch) | |
tree | be731f914364e5b001db4e367be87f53fc2a4a12 | |
parent | 5df63c2a149ae65a9ec239e7c2af44efa6f79beb (diff) |
lib: fix stall in __bitmap_parselist()
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/[email protected]
Fixes: 0a5ce0831d04382a ("lib/bitmap.c: make bitmap_parselist() thread-safe and much faster")
Signed-off-by: Yury Norov <[email protected]>
Reported-by: Tetsuo Handa <[email protected]>
Reported-by: syzbot <[email protected]>
Cc: Noam Camus <[email protected]>
Cc: Rasmus Villemoes <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | lib/bitmap.c | 2 | ||||
-rw-r--r-- | lib/test_bitmap.c | 4 |
2 files changed, 5 insertions, 1 deletions
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 b3f235baa05d..413367cf569e 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}, }; |