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

Commit 9bf98f16 authored by Pan Xinhui's avatar Pan Xinhui Committed by Linus Torvalds
Browse files

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: default avatarPan 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d9282cb6
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -506,7 +506,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
		int nmaskbits)
{
	unsigned a, b;
	int c, old_c, totaldigits;
	int c, old_c, totaldigits, ndigits;
	const char __user __force *ubuf = (const char __user __force *)buf;
	int at_start, in_range;

@@ -516,6 +516,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
		at_start = 1;
		in_range = 0;
		a = b = 0;
		ndigits = totaldigits;

		/* Get the next cpu# or a range of cpu#'s */
		while (buflen) {
@@ -529,17 +530,20 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
			if (isspace(c))
				continue;

			/*
			 * If the last character was a space and the current
			 * character isn't '\0', we've got embedded whitespace.
			 * This is a no-no, so throw an error.
			 */
			if (totaldigits && c && isspace(old_c))
				return -EINVAL;

			/* A '\0' or a ',' signal the end of a cpu# or range */
			if (c == '\0' || c == ',')
				break;
			/*
			* whitespaces between digits are not allowed,
			* but it's ok if whitespaces are on head or tail.
			* when old_c is whilespace,
			* if totaldigits == ndigits, whitespace is on head.
			* if whitespace is on tail, it should not run here.
			* as c was ',' or '\0',
			* the last code line has broken the current loop.
			*/
			if ((totaldigits != ndigits) && isspace(old_c))
				return -EINVAL;

			if (c == '-') {
				if (at_start || in_range)
@@ -559,6 +563,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
			at_start = 0;
			totaldigits++;
		}
		if (ndigits == totaldigits)
			continue;
		/* if no digit is after '-', it's wrong*/
		if (at_start && in_range)
			return -EINVAL;
@@ -566,12 +572,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
			return -EINVAL;
		if (b >= nmaskbits)
			return -ERANGE;
		if (!at_start) {
		while (a <= b) {
			set_bit(a, maskp);
			a++;
		}
		}
	} while (buflen && c == ',');
	return 0;
}