__bitmap_parselist: fix bug in empty string handling
bitmap_parselist("", &mask, nmaskbits) will erroneously set bit zero in the mask. The same bug is visible in cpumask_parselist() since it is layered on top of the bitmask code, e.g. if you boot with "isolcpus=", you will actually end up with cpu zero isolated. The bug was introduced in commit4b060420a5
("bitmap, irq: add smp_affinity_list interface to /proc/irq") when bitmap_parselist() was generalized to support userspace as well as kernelspace. Fixes:4b060420a5
("bitmap, irq: add smp_affinity_list interface to /proc/irq") Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
4f973c63d1
Коммит
2528a8b8f4
17
lib/bitmap.c
17
lib/bitmap.c
|
@ -506,12 +506,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
unsigned a, b;
|
unsigned a, b;
|
||||||
int c, old_c, totaldigits;
|
int c, old_c, totaldigits;
|
||||||
const char __user __force *ubuf = (const char __user __force *)buf;
|
const char __user __force *ubuf = (const char __user __force *)buf;
|
||||||
int exp_digit, in_range;
|
int at_start, in_range;
|
||||||
|
|
||||||
totaldigits = c = 0;
|
totaldigits = c = 0;
|
||||||
bitmap_zero(maskp, nmaskbits);
|
bitmap_zero(maskp, nmaskbits);
|
||||||
do {
|
do {
|
||||||
exp_digit = 1;
|
at_start = 1;
|
||||||
in_range = 0;
|
in_range = 0;
|
||||||
a = b = 0;
|
a = b = 0;
|
||||||
|
|
||||||
|
@ -540,11 +540,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
if (exp_digit || in_range)
|
if (at_start || in_range)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
b = 0;
|
b = 0;
|
||||||
in_range = 1;
|
in_range = 1;
|
||||||
exp_digit = 1;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,16 +553,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||||
b = b * 10 + (c - '0');
|
b = b * 10 + (c - '0');
|
||||||
if (!in_range)
|
if (!in_range)
|
||||||
a = b;
|
a = b;
|
||||||
exp_digit = 0;
|
at_start = 0;
|
||||||
totaldigits++;
|
totaldigits++;
|
||||||
}
|
}
|
||||||
if (!(a <= b))
|
if (!(a <= b))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (b >= nmaskbits)
|
if (b >= nmaskbits)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
while (a <= b) {
|
if (!at_start) {
|
||||||
set_bit(a, maskp);
|
while (a <= b) {
|
||||||
a++;
|
set_bit(a, maskp);
|
||||||
|
a++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (buflen && c == ',');
|
} while (buflen && c == ',');
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче