[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20181223094422.4849-3-ynorov@marvell.com>
Date: Sun, 23 Dec 2018 09:44:47 +0000
From: Yuri Norov <ynorov@...vell.com>
To: Andrew Morton <akpm@...ux-foundation.org>,
Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
Rasmus Villemoes <linux@...musvillemoes.dk>,
Arnd Bergmann <arnd@...db.de>,
Kees Cook <keescook@...omium.org>,
Matthew Wilcox <willy@...radead.org>,
Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
CC: Yuri Norov <ynorov@...vell.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: [PATCH 2/4] bitmap_parselist: move part of logic to helpers
Move region checking and setting functionality of __bitmap_parselist()
to helpers.
Signed-off-by: Yury Norov <ynorov@...vell.com>
---
lib/bitmap.c | 64 +++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 53 insertions(+), 11 deletions(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c
index ad43ba397c58..a60fd9723677 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -477,6 +477,42 @@ int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
}
EXPORT_SYMBOL(bitmap_print_to_pagebuf);
+/*
+ * Region 9-38:4/10 describes the following bitmap structure:
+ * 0 9 12 18 38
+ * .........****......****......****......
+ * ^ ^ ^ ^
+ * start off grlen end
+ */
+struct region {
+ unsigned int start;
+ unsigned int off;
+ unsigned int grlen;
+ unsigned int end;
+};
+
+static int bitmap_set_region(const struct region *r,
+ unsigned long *bitmap, int nbits)
+{
+ unsigned int start;
+
+ if (r->end >= nbits)
+ return -ERANGE;
+
+ for (start = r->start; start <= r->end; start += r->grlen)
+ bitmap_set(bitmap, start, min(r->end - start + 1, r->off));
+
+ return 0;
+}
+
+static int bitmap_check_region(const struct region *r)
+{
+ if (r->start > r->end || r->grlen == 0 || r->off > r->grlen)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* __bitmap_parselist - convert list format ASCII string to bitmap
* @buf: read nul-terminated user string from this buffer
@@ -507,10 +543,11 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
int nmaskbits)
{
unsigned int a, b, old_a, old_b;
- unsigned int group_size, used_size, off;
+ unsigned int group_size, used_size;
int c, old_c, totaldigits, ndigits;
const char __user __force *ubuf = (const char __user __force *)buf;
- int at_start, in_range, in_partial_range;
+ int at_start, in_range, in_partial_range, ret;
+ struct region r;
totaldigits = c = 0;
old_a = old_b = 0;
@@ -599,15 +636,20 @@ 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) || group_size == 0 || !(used_size <= group_size))
- return -EINVAL;
- if (b >= nmaskbits)
- return -ERANGE;
- while (a <= b) {
- off = min(b - a + 1, used_size);
- bitmap_set(maskp, a, off);
- a += group_size;
- }
+
+ r.start = a;
+ r.off = used_size;
+ r.grlen = group_size;
+ r.end = b;
+
+ ret = bitmap_check_region(&r);
+ if (ret)
+ return ret;
+
+ ret = bitmap_set_region(&r, maskp, nmaskbits);
+ if (ret)
+ return ret;
+
} while (buflen && c == ',');
return 0;
}
--
2.17.1
Powered by blists - more mailing lists