summaryrefslogtreecommitdiff
path: root/lib/bitmap-str.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bitmap-str.c')
-rw-r--r--lib/bitmap-str.c24
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;