Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2528a8b8 authored by Chris Metcalf's avatar Chris Metcalf Committed by Linus Torvalds
Browse files

__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 commit 4b060420 ("bitmap, irq: add
smp_affinity_list interface to /proc/irq") when bitmap_parselist() was
generalized to support userspace as well as kernelspace.

Fixes: 4b060420 ("bitmap, irq: add smp_affinity_list interface to /proc/irq")
Signed-off-by: default avatarChris Metcalf <cmetcalf@ezchip.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4f973c63
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -506,12 +506,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
	unsigned a, b;
	int c, old_c, totaldigits;
	const char __user __force *ubuf = (const char __user __force *)buf;
	int exp_digit, in_range;
	int at_start, in_range;

	totaldigits = c = 0;
	bitmap_zero(maskp, nmaskbits);
	do {
		exp_digit = 1;
		at_start = 1;
		in_range = 0;
		a = b = 0;

@@ -540,11 +540,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
				break;

			if (c == '-') {
				if (exp_digit || in_range)
				if (at_start || in_range)
					return -EINVAL;
				b = 0;
				in_range = 1;
				exp_digit = 1;
				continue;
			}

@@ -554,17 +553,19 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
			b = b * 10 + (c - '0');
			if (!in_range)
				a = b;
			exp_digit = 0;
			at_start = 0;
			totaldigits++;
		}
		if (!(a <= b))
			return -EINVAL;
		if (b >= nmaskbits)
			return -ERANGE;
		if (!at_start) {
			while (a <= b) {
				set_bit(a, maskp);
				a++;
			}
		}
	} while (buflen && c == ',');
	return 0;
}