Skip to content

Commit 9bf98f1

Browse files
Pan Xinhuitorvalds
authored andcommitted
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>
1 parent d9282cb commit 9bf98f1

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

lib/bitmap.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
506506
int nmaskbits)
507507
{
508508
unsigned a, b;
509-
int c, old_c, totaldigits;
509+
int c, old_c, totaldigits, ndigits;
510510
const char __user __force *ubuf = (const char __user __force *)buf;
511511
int at_start, in_range;
512512

@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
516516
at_start = 1;
517517
in_range = 0;
518518
a = b = 0;
519+
ndigits = totaldigits;
519520

520521
/* Get the next cpu# or a range of cpu#'s */
521522
while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
529530
if (isspace(c))
530531
continue;
531532

532-
/*
533-
* If the last character was a space and the current
534-
* character isn't '\0', we've got embedded whitespace.
535-
* This is a no-no, so throw an error.
536-
*/
537-
if (totaldigits && c && isspace(old_c))
538-
return -EINVAL;
539-
540533
/* A '\0' or a ',' signal the end of a cpu# or range */
541534
if (c == '\0' || c == ',')
542535
break;
536+
/*
537+
* whitespaces between digits are not allowed,
538+
* but it's ok if whitespaces are on head or tail.
539+
* when old_c is whilespace,
540+
* if totaldigits == ndigits, whitespace is on head.
541+
* if whitespace is on tail, it should not run here.
542+
* as c was ',' or '\0',
543+
* the last code line has broken the current loop.
544+
*/
545+
if ((totaldigits != ndigits) && isspace(old_c))
546+
return -EINVAL;
543547

544548
if (c == '-') {
545549
if (at_start || in_range)
@@ -559,18 +563,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
559563
at_start = 0;
560564
totaldigits++;
561565
}
566+
if (ndigits == totaldigits)
567+
continue;
562568
/* if no digit is after '-', it's wrong*/
563569
if (at_start && in_range)
564570
return -EINVAL;
565571
if (!(a <= b))
566572
return -EINVAL;
567573
if (b >= nmaskbits)
568574
return -ERANGE;
569-
if (!at_start) {
570-
while (a <= b) {
571-
set_bit(a, maskp);
572-
a++;
573-
}
575+
while (a <= b) {
576+
set_bit(a, maskp);
577+
a++;
574578
}
575579
} while (buflen && c == ',');
576580
return 0;

0 commit comments

Comments
 (0)