lib/bitmap.c: bitmap_parselist can accept string with whitespaces on head or tail
In __bitmap_parselist we can accept whitespaces on head or tail during every parsing procedure. If input has valid ranges, there is no reason to reject the user. For example, bitmap_parselist(" 1-3, 5, ", &mask, nmaskbits). After separating the string, we get " 1-3", " 5", and " ". It's possible and reasonable to accept such string as long as the parsing result is correct. Signed-off-by: Pan Xinhui <xinhuix.pan@intel.com> Cc: Yury Norov <yury.norov@gmail.com> Cc: Chris Metcalf <cmetcalf@ezchip.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Sudeep Holla <sudeep.holla@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
d9282cb663
commit
9bf98f168b
32
lib/bitmap.c
32
lib/bitmap.c
|
@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
|||
int nmaskbits)
|
||||
{
|
||||
unsigned a, b;
|
||||
int c, old_c, totaldigits;
|
||||
int c, old_c, totaldigits, ndigits;
|
||||
const char __user __force *ubuf = (const char __user __force *)buf;
|
||||
int at_start, in_range;
|
||||
|
||||
|
@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
|||
at_start = 1;
|
||||
in_range = 0;
|
||||
a = b = 0;
|
||||
ndigits = totaldigits;
|
||||
|
||||
/* Get the next cpu# or a range of cpu#'s */
|
||||
while (buflen) {
|
||||
|
@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
|||
if (isspace(c))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the last character was a space and the current
|
||||
* character isn't '\0', we've got embedded whitespace.
|
||||
* This is a no-no, so throw an error.
|
||||
*/
|
||||
if (totaldigits && c && isspace(old_c))
|
||||
return -EINVAL;
|
||||
|
||||
/* A '\0' or a ',' signal the end of a cpu# or range */
|
||||
if (c == '\0' || c == ',')
|
||||
break;
|
||||
/*
|
||||
* whitespaces between digits are not allowed,
|
||||
* but it's ok if whitespaces are on head or tail.
|
||||
* when old_c is whilespace,
|
||||
* if totaldigits == ndigits, whitespace is on head.
|
||||
* if whitespace is on tail, it should not run here.
|
||||
* as c was ',' or '\0',
|
||||
* the last code line has broken the current loop.
|
||||
*/
|
||||
if ((totaldigits != ndigits) && isspace(old_c))
|
||||
return -EINVAL;
|
||||
|
||||
if (c == '-') {
|
||||
if (at_start || in_range)
|
||||
|
@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
|||
at_start = 0;
|
||||
totaldigits++;
|
||||
}
|
||||
if (ndigits == totaldigits)
|
||||
continue;
|
||||
/* if no digit is after '-', it's wrong*/
|
||||
if (at_start && in_range)
|
||||
return -EINVAL;
|
||||
|
@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
|||
return -EINVAL;
|
||||
if (b >= nmaskbits)
|
||||
return -ERANGE;
|
||||
if (!at_start) {
|
||||
while (a <= b) {
|
||||
set_bit(a, maskp);
|
||||
a++;
|
||||
}
|
||||
while (a <= b) {
|
||||
set_bit(a, maskp);
|
||||
a++;
|
||||
}
|
||||
} while (buflen && c == ',');
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue