diff options
Diffstat (limited to 'lib/bitmap-str.c')
| -rw-r--r-- | lib/bitmap-str.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c index dd9aa0635fa5..cafd6388892f 100644 --- a/lib/bitmap-str.c +++ b/lib/bitmap-str.c @@ -8,6 +8,7 @@ #include <linux/hex.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/overflow.h> #include <linux/string.h> #include "kstrtox.h" @@ -186,10 +187,12 @@ struct region { static void bitmap_set_region(const struct region *r, unsigned long *bitmap) { - unsigned int start; + unsigned int start = r->start; - for (start = r->start; start <= r->end; start += r->group_len) + do { bitmap_set(bitmap, start, min(r->end - start + 1, r->off)); + } while (!check_add_overflow(start, r->group_len, &start) && + start <= r->end); } static int bitmap_check_region(const struct region *r) @@ -299,7 +302,14 @@ check_pattern: if (*str != '/') return ERR_PTR(-EINVAL); - return bitmap_getnum(str + 1, &r->group_len, lastbit); + str = bitmap_getnum(str + 1, &r->group_len, lastbit); + if (IS_ERR(str)) + return str; + + if (!end_of_region(*str)) + return ERR_PTR(-EINVAL); + + return end_of_str(*str) ? NULL : str; no_end: r->end = r->start; @@ -414,8 +424,12 @@ static const char *bitmap_get_x32_reverse(const char *start, goto out; } - if (hex_to_bin(*end--) >= 0) - return ERR_PTR(-EOVERFLOW); + /* + * Eight digits have been consumed and the next character is not a + * separator: another hex digit means the chunk does not fit in 32 + * bits, anything else is an illegal character. + */ + return ERR_PTR(hex_to_bin(*end) >= 0 ? -EOVERFLOW : -EINVAL); out: *num = ret; return end; |
