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
1 changed files with 18 additions and 14 deletions
32
lib/bitmap.c
32
lib/bitmap.c
|
@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
int nmaskbits)
|
int nmaskbits)
|
||||||
{
|
{
|
||||||
unsigned a, b;
|
unsigned a, b;
|
||||||
int c, old_c, totaldigits;
|
int c, old_c, totaldigits, ndigits;
|
||||||
const char __user __force *ubuf = (const char __user __force *)buf;
|
const char __user __force *ubuf = (const char __user __force *)buf;
|
||||||
int at_start, in_range;
|
int at_start, in_range;
|
||||||
|
|
||||||
|
@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
at_start = 1;
|
at_start = 1;
|
||||||
in_range = 0;
|
in_range = 0;
|
||||||
a = b = 0;
|
a = b = 0;
|
||||||
|
ndigits = totaldigits;
|
||||||
|
|
||||||
/* Get the next cpu# or a range of cpu#'s */
|
/* Get the next cpu# or a range of cpu#'s */
|
||||||
while (buflen) {
|
while (buflen) {
|
||||||
|
@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
if (isspace(c))
|
if (isspace(c))
|
||||||
continue;
|
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 */
|
/* A '\0' or a ',' signal the end of a cpu# or range */
|
||||||
if (c == '\0' || c == ',')
|
if (c == '\0' || c == ',')
|
||||||
break;
|
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 (c == '-') {
|
||||||
if (at_start || in_range)
|
if (at_start || in_range)
|
||||||
|
@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
at_start = 0;
|
at_start = 0;
|
||||||
totaldigits++;
|
totaldigits++;
|
||||||
}
|
}
|
||||||
|
if (ndigits == totaldigits)
|
||||||
|
continue;
|
||||||
/* if no digit is after '-', it's wrong*/
|
/* if no digit is after '-', it's wrong*/
|
||||||
if (at_start && in_range)
|
if (at_start && in_range)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (b >= nmaskbits)
|
if (b >= nmaskbits)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
if (!at_start) {
|
while (a <= b) {
|
||||||
while (a <= b) {
|
set_bit(a, maskp);
|
||||||
set_bit(a, maskp);
|
a++;
|
||||||
a++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (buflen && c == ',');
|
} while (buflen && c == ',');
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue