aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPan Xinhui <xinhuix.pan@intel.com>2015-09-09 18:37:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-10 16:29:01 -0400
commit9bf98f168b7b004c94c766a6989071e0f858def3 (patch)
tree8639fa0b9de8011692d06d06d6756ff372d3f5f0 /lib
parentd9282cb66353be502aae09aae75d05a6863eb979 (diff)
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/bitmap.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c
index f549176e9250..814814397cce 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
506 int nmaskbits) 506 int nmaskbits)
507{ 507{
508 unsigned a, b; 508 unsigned a, b;
509 int c, old_c, totaldigits; 509 int c, old_c, totaldigits, ndigits;
510 const char __user __force *ubuf = (const char __user __force *)buf; 510 const char __user __force *ubuf = (const char __user __force *)buf;
511 int at_start, in_range; 511 int at_start, in_range;
512 512
@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
516 at_start = 1; 516 at_start = 1;
517 in_range = 0; 517 in_range = 0;
518 a = b = 0; 518 a = b = 0;
519 ndigits = totaldigits;
519 520
520 /* Get the next cpu# or a range of cpu#'s */ 521 /* Get the next cpu# or a range of cpu#'s */
521 while (buflen) { 522 while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
529 if (isspace(c)) 530 if (isspace(c))
530 continue; 531 continue;
531 532
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
540 /* A '\0' or a ',' signal the end of a cpu# or range */ 533 /* A '\0' or a ',' signal the end of a cpu# or range */
541 if (c == '\0' || c == ',') 534 if (c == '\0' || c == ',')
542 break; 535 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;
543 547
544 if (c == '-') { 548 if (c == '-') {
545 if (at_start || in_range) 549 if (at_start || in_range)
@@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
559 at_start = 0; 563 at_start = 0;
560 totaldigits++; 564 totaldigits++;
561 } 565 }
566 if (ndigits == totaldigits)
567 continue;
562 /* if no digit is after '-', it's wrong*/ 568 /* if no digit is after '-', it's wrong*/
563 if (at_start && in_range) 569 if (at_start && in_range)
564 return -EINVAL; 570 return -EINVAL;
@@ -566,11 +572,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
566 return -EINVAL; 572 return -EINVAL;
567 if (b >= nmaskbits) 573 if (b >= nmaskbits)
568 return -ERANGE; 574 return -ERANGE;
569 if (!at_start) { 575 while (a <= b) {
570 while (a <= b) { 576 set_bit(a, maskp);
571 set_bit(a, maskp); 577 a++;
572 a++;
573 }
574 } 578 }
575 } while (buflen && c == ','); 579 } while (buflen && c == ',');
576 return 0; 580 return 0;