diff options
-rw-r--r-- | lib/bitmap.c | 32 |
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; |