]>
Commit | Line | Data |
---|---|---|
7f94bc7a GKH |
1 | From 2528a8b8f457d7432552d0e2b6f0f4046bb702f4 Mon Sep 17 00:00:00 2001 |
2 | From: Chris Metcalf <cmetcalf@ezchip.com> | |
3 | Date: Thu, 25 Jun 2015 15:02:08 -0700 | |
4 | Subject: __bitmap_parselist: fix bug in empty string handling | |
5 | ||
6 | From: Chris Metcalf <cmetcalf@ezchip.com> | |
7 | ||
8 | commit 2528a8b8f457d7432552d0e2b6f0f4046bb702f4 upstream. | |
9 | ||
10 | bitmap_parselist("", &mask, nmaskbits) will erroneously set bit zero in | |
11 | the mask. The same bug is visible in cpumask_parselist() since it is | |
12 | layered on top of the bitmask code, e.g. if you boot with "isolcpus=", | |
13 | you will actually end up with cpu zero isolated. | |
14 | ||
15 | The bug was introduced in commit 4b060420a596 ("bitmap, irq: add | |
16 | smp_affinity_list interface to /proc/irq") when bitmap_parselist() was | |
17 | generalized to support userspace as well as kernelspace. | |
18 | ||
19 | Fixes: 4b060420a596 ("bitmap, irq: add smp_affinity_list interface to /proc/irq") | |
20 | Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com> | |
21 | Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> | |
22 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
23 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
24 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
25 | ||
26 | --- | |
27 | lib/bitmap.c | 17 +++++++++-------- | |
28 | 1 file changed, 9 insertions(+), 8 deletions(-) | |
29 | ||
30 | --- a/lib/bitmap.c | |
31 | +++ b/lib/bitmap.c | |
32 | @@ -506,12 +506,12 @@ static int __bitmap_parselist(const char | |
33 | unsigned a, b; | |
34 | int c, old_c, totaldigits; | |
35 | const char __user __force *ubuf = (const char __user __force *)buf; | |
36 | - int exp_digit, in_range; | |
37 | + int at_start, in_range; | |
38 | ||
39 | totaldigits = c = 0; | |
40 | bitmap_zero(maskp, nmaskbits); | |
41 | do { | |
42 | - exp_digit = 1; | |
43 | + at_start = 1; | |
44 | in_range = 0; | |
45 | a = b = 0; | |
46 | ||
47 | @@ -540,11 +540,10 @@ static int __bitmap_parselist(const char | |
48 | break; | |
49 | ||
50 | if (c == '-') { | |
51 | - if (exp_digit || in_range) | |
52 | + if (at_start || in_range) | |
53 | return -EINVAL; | |
54 | b = 0; | |
55 | in_range = 1; | |
56 | - exp_digit = 1; | |
57 | continue; | |
58 | } | |
59 | ||
60 | @@ -554,16 +553,18 @@ static int __bitmap_parselist(const char | |
61 | b = b * 10 + (c - '0'); | |
62 | if (!in_range) | |
63 | a = b; | |
64 | - exp_digit = 0; | |
65 | + at_start = 0; | |
66 | totaldigits++; | |
67 | } | |
68 | if (!(a <= b)) | |
69 | return -EINVAL; | |
70 | if (b >= nmaskbits) | |
71 | return -ERANGE; | |
72 | - while (a <= b) { | |
73 | - set_bit(a, maskp); | |
74 | - a++; | |
75 | + if (!at_start) { | |
76 | + while (a <= b) { | |
77 | + set_bit(a, maskp); | |
78 | + a++; | |
79 | + } | |
80 | } | |
81 | } while (buflen && c == ','); | |
82 | return 0; |