* [PATCH 1/6] bitmap: bitmap_parse(): reject non-hex character before 8 digits
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 10:23 ` [PATCH 2/6] bitmap: test bitmap_parse() with an illegal character before 8 hex digits shashank
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
bitmap_parse() is documented to return -EINVAL for illegal characters,
and it does so everywhere except when the illegal character directly
precedes a chunk of exactly eight hex digits.
bitmap_get_x32_reverse() parses a chunk from right to left. After it
has consumed eight digits it looks at one more character: a hex digit
means the chunk is wider than 32 bits and -EOVERFLOW is returned. Any
other character is silently consumed as if it were a separator, and the
remaining input is parsed as the next chunk. As a result:
"x12345678" -> 0x12345678, returns 0 (expected -EINVAL)
"1g12345678" -> 0x1_12345678, returns 0 (expected -EINVAL)
"0x0000000f" -> 0xf, returns 0, while "0xf" returns -EINVAL
bitmap_parse() backs cpumask_parse() and cpumask_parse_user(), so the
same inconsistency is visible when writing masks such as
/proc/irq/*/smp_affinity or the network queue rps_cpus/xps_cpus files.
__bitmap_parse(), which this function replaced in commit 2d6261583be0
("lib: rework bitmap_parse()"), rejected all three strings with -EINVAL,
and a "0x" prefix is accepted today only when exactly eight digits
follow it, so no reliably working input is lost.
When the loop falls through, *end is known to be a non-separator
character inside the buffer, so return -EOVERFLOW if it is a hex digit
and -EINVAL otherwise.
Fixes: 2d6261583be0 ("lib: rework bitmap_parse()")
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/bitmap-str.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c
index dd9aa0635fa5..e02c5bc80951 100644
--- a/lib/bitmap-str.c
+++ b/lib/bitmap-str.c
@@ -414,8 +414,12 @@ static const char *bitmap_get_x32_reverse(const char *start,
goto out;
}
- if (hex_to_bin(*end--) >= 0)
- return ERR_PTR(-EOVERFLOW);
+ /*
+ * Eight digits have been consumed and the next character is not a
+ * separator: another hex digit means the chunk does not fit in 32
+ * bits, anything else is an illegal character.
+ */
+ return ERR_PTR(hex_to_bin(*end) >= 0 ? -EOVERFLOW : -EINVAL);
out:
*num = ret;
return end;
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 2/6] bitmap: test bitmap_parse() with an illegal character before 8 hex digits
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
2026-09-25 10:23 ` [PATCH 1/6] bitmap: bitmap_parse(): reject non-hex character before 8 digits shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 10:23 ` [PATCH 3/6] bitmap: bitmap_parselist(): reject trailing characters after group size shashank
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
Add bitmap_parse() cases where an illegal character directly precedes a
chunk of eight hex digits. These were accepted before the previous
patch and must return -EINVAL.
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/test_bitmap.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 56bd23059b26..35bb18f6e326 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -643,6 +643,10 @@ static const struct test_bitmap_parselist parse_tests[] __initconst = {
{-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 90, 0},
{-EOVERFLOW, "fbadf00d,deadbeef,1,0", NULL, 95, 0},
{-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 100, 0},
+
+ {-EINVAL, "x12345678", NULL, 32, 0},
+ {-EINVAL, "1g12345678", NULL, 64, 0},
+ {-EINVAL, "0x0000000f", NULL, 64, 0},
#undef step
};
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 3/6] bitmap: bitmap_parselist(): reject trailing characters after group size
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
2026-09-25 10:23 ` [PATCH 1/6] bitmap: bitmap_parse(): reject non-hex character before 8 digits shashank
2026-09-25 10:23 ` [PATCH 2/6] bitmap: test bitmap_parse() with an illegal character before 8 hex digits shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 10:23 ` [PATCH 4/6] bitmap: test bitmap_parselist() with text after the " shashank
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
bitmap_parse_region() checks that every region ends at a separator
(',', whitespace, '\n' or '\0'), except in the "range:used/group" form:
after parsing the group size it returns the pointer to the following
character without looking at it. The caller then starts a new region
at that character.
Before 'N' and 'all' were accepted as region starts this happened to be
harmless, because any other character would fail to parse as a new
region. Now text directly following the group size is silently parsed
as another region:
"0-7:1/2N" -> bits 0,2,4,6,7 (nbits = 8), returns 0
"0-7:1/2all" -> all bits set, returns 0
while "0-7N", "5N" or "0-7:1/2x" are correctly rejected with -EINVAL.
bitmap_parselist() is documented to return -EINVAL for an invalid
character. It parses cpu lists from sysfs, cgroup cpuset files and
boot parameters such as isolcpus= and nohz_full=, so a typo there is
accepted and yields a different mask than intended.
Check for the end of the region after the group size as well, like the
other forms do.
Fixes: 2c4885d24e64 ("lib: bitmap: support "N" as an alias for size of bitmap")
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/bitmap-str.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c
index e02c5bc80951..b58966864657 100644
--- a/lib/bitmap-str.c
+++ b/lib/bitmap-str.c
@@ -299,7 +299,14 @@ static const char *bitmap_parse_region(const char *str, struct region *r)
if (*str != '/')
return ERR_PTR(-EINVAL);
- return bitmap_getnum(str + 1, &r->group_len, lastbit);
+ str = bitmap_getnum(str + 1, &r->group_len, lastbit);
+ if (IS_ERR(str))
+ return str;
+
+ if (!end_of_region(*str))
+ return ERR_PTR(-EINVAL);
+
+ return end_of_str(*str) ? NULL : str;
no_end:
r->end = r->start;
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 4/6] bitmap: test bitmap_parselist() with text after the group size
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
` (2 preceding siblings ...)
2026-09-25 10:23 ` [PATCH 3/6] bitmap: bitmap_parselist(): reject trailing characters after group size shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 10:23 ` [PATCH 5/6] bitmap: bitmap_parselist(): don't wrap around on a huge " shashank
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
Add bitmap_parselist() cases where 'N' or 'all' directly follows the
group size of a "range:used/group" region. These were accepted before
"bitmap: bitmap_parselist(): reject trailing characters after group
size" and must return -EINVAL.
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/test_bitmap.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 35bb18f6e326..f316a82840f5 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -528,6 +528,9 @@ static const struct test_bitmap_parselist parselist_tests[] __initconst = {
{-EINVAL, "a-31:10/1", NULL, 8, 0},
{-EINVAL, "0-31:a/1", NULL, 8, 0},
{-EINVAL, "0-\n", NULL, 8, 0},
+ {-EINVAL, "0-7:1/2N", NULL, 8, 0},
+ {-EINVAL, "0-7:1/2all", NULL, 8, 0},
+ {-EINVAL, "all:1/2N", NULL, 8, 0},
};
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 5/6] bitmap: bitmap_parselist(): don't wrap around on a huge group size
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
` (3 preceding siblings ...)
2026-09-25 10:23 ` [PATCH 4/6] bitmap: test bitmap_parselist() with text after the " shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 10:23 ` [PATCH 6/6] bitmap: test bitmap_parselist() with a group size close to UINT_MAX shashank
2026-09-25 17:05 ` [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() Yury Norov
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
In the "range:used/group" form bitmap_set_region() walks the range with
for (start = r->start; start <= r->end; start += r->group_len)
where all values are unsigned int. bitmap_getnum() accepts any group
size up to UINT_MAX, and bitmap_check_region() only requires it to be
non-zero and at least the used size. If start + group_len exceeds
UINT_MAX, start wraps around to a small value that is still <= end, and
bits below the start of the range get set:
"1-1:1/4294967295" -> bits 0,1 (expected bit 1)
"15-15:1/4294967281" -> bits 0,15 (expected bit 15)
The loop still terminates, because start keeps decreasing until it
wraps past zero again, but the resulting mask contains bits outside
the requested range.
This needs a group size within 'start' of UINT_MAX, so it is unlikely
to be hit by accident; all bits set stay below the end of the range,
so there is no out-of-bounds write.
A group larger than the range simply means that the range contains a
single group, so stop the walk when the next group would start beyond
UINT_MAX.
Fixes: 0a5ce0831d04 ("lib/bitmap.c: make bitmap_parselist() thread-safe and much faster")
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/bitmap-str.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c
index b58966864657..cafd6388892f 100644
--- a/lib/bitmap-str.c
+++ b/lib/bitmap-str.c
@@ -8,6 +8,7 @@
#include <linux/hex.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/overflow.h>
#include <linux/string.h>
#include "kstrtox.h"
@@ -186,10 +187,12 @@ struct region {
static void bitmap_set_region(const struct region *r, unsigned long *bitmap)
{
- unsigned int start;
+ unsigned int start = r->start;
- for (start = r->start; start <= r->end; start += r->group_len)
+ do {
bitmap_set(bitmap, start, min(r->end - start + 1, r->off));
+ } while (!check_add_overflow(start, r->group_len, &start) &&
+ start <= r->end);
}
static int bitmap_check_region(const struct region *r)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 6/6] bitmap: test bitmap_parselist() with a group size close to UINT_MAX
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
` (4 preceding siblings ...)
2026-09-25 10:23 ` [PATCH 5/6] bitmap: bitmap_parselist(): don't wrap around on a huge " shashank
@ 2026-09-25 10:23 ` shashank
2026-09-25 17:05 ` [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() Yury Norov
6 siblings, 0 replies; 10+ messages in thread
From: shashank @ 2026-09-25 10:23 UTC (permalink / raw)
To: Yury Norov; +Cc: Rasmus Villemoes, Andrew Morton, linux-kernel
Add bitmap_parselist() cases where the group size makes start +
group_len overflow an unsigned int. Before "bitmap: bitmap_parselist():
don't wrap around on a huge group size" the region walk wrapped around
and also set bit 0.
Assisted-by: LLM
Signed-off-by: shashank <jain.sm@gmail.com>
---
lib/test_bitmap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index f316a82840f5..ba09d057f47f 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -502,6 +502,8 @@ static const struct test_bitmap_parselist parselist_tests[] __initconst = {
{0, "0-N:1/3,1-N:1/3,2-N:1/3", &exp1[8 * step], 32, 0},
{0, "0-31:1/3,1-31:1/3,2-31:1/3", &exp1[8 * step], 32, 0},
{0, "1-10:8/12,8-31:24/29,0-31:0/3", &exp1[9 * step], 32, 0},
+ {0, "1-1:1/4294967295", &exp1[1 * step], 32, 0},
+ {0, "15-15:1/4294967281", &exp1[13 * step], 32, 0},
{0, "all", &exp1[8 * step], 32, 0},
{0, "0, 1, all, ", &exp1[8 * step], 32, 0},
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist()
2026-09-25 10:23 [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() shashank
` (5 preceding siblings ...)
2026-09-25 10:23 ` [PATCH 6/6] bitmap: test bitmap_parselist() with a group size close to UINT_MAX shashank
@ 2026-09-25 17:05 ` Yury Norov
2026-09-25 20:39 ` Andrew Morton
6 siblings, 1 reply; 10+ messages in thread
From: Yury Norov @ 2026-09-25 17:05 UTC (permalink / raw)
To: shashank; +Cc: Yury Norov, Rasmus Villemoes, Andrew Morton, linux-kernel
On Fri, Sep 25, 2026 at 03:53:01PM +0530, shashank wrote:
> This series fixes three cases where the bitmap string parsers accept
> input they are documented to reject, or produce a different mask than
> the one requested. Each fix is followed by a patch adding the failing
> cases to lib/test_bitmap.c.
>
> 1-2: bitmap_parse() treats a non-hex character directly before a chunk
> of exactly eight hex digits as a separator, so "x12345678" and
> "0x0000000f" are accepted while "0xf" is rejected. This is a
> regression from the bitmap_parse() rework; the old __bitmap_parse()
> rejected all of them.
>
> 3-4: bitmap_parselist() does not check for the end of the region after
> the group size of a "range:used/group" region, so since N and
> all became valid region starts, "0-7:1/2N" or "0-7:1/2all" are
> silently parsed as two regions.
>
> 5-6: bitmap_parselist() walks a "range:used/group" region with an
> unsigned int that wraps around when the group size is close to
> UINT_MAX, setting bits below the requested range. This needs an
> absurd group size and never writes out of bounds.
>
> With the series applied, test_bitmap reports "all 391544 tests passed"
> (UML, x86_64). The three fixes are independent and can be applied in
> any order.
That looks reasonable, but please resend the series with your full
real name, and also specify the version of LLM you've used to prepare
the series. I'm uncomfortable taking anonymous commitments.
Thanks,
Yury
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist()
2026-09-25 17:05 ` [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist() Yury Norov
@ 2026-09-25 20:39 ` Andrew Morton
2026-09-26 14:02 ` Yury Norov
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Morton @ 2026-09-25 20:39 UTC (permalink / raw)
To: Yury Norov; +Cc: shashank, Yury Norov, Rasmus Villemoes, linux-kernel
On Fri, 25 Sep 2026 13:05:06 -0400 Yury Norov <ynorov@nvidia.com> wrote:
> On Fri, Sep 25, 2026 at 03:53:01PM +0530, shashank wrote:
> > This series fixes three cases where the bitmap string parsers accept
> > input they are documented to reject, or produce a different mask than
> > the one requested. Each fix is followed by a patch adding the failing
> > cases to lib/test_bitmap.c.
> >
> > 1-2: bitmap_parse() treats a non-hex character directly before a chunk
> > of exactly eight hex digits as a separator, so "x12345678" and
> > "0x0000000f" are accepted while "0xf" is rejected. This is a
> > regression from the bitmap_parse() rework; the old __bitmap_parse()
> > rejected all of them.
> >
> > 3-4: bitmap_parselist() does not check for the end of the region after
> > the group size of a "range:used/group" region, so since N and
> > all became valid region starts, "0-7:1/2N" or "0-7:1/2all" are
> > silently parsed as two regions.
> >
> > 5-6: bitmap_parselist() walks a "range:used/group" region with an
> > unsigned int that wraps around when the group size is close to
> > UINT_MAX, setting bits below the requested range. This needs an
> > absurd group size and never writes out of bounds.
> >
> > With the series applied, test_bitmap reports "all 391544 tests passed"
> > (UML, x86_64). The three fixes are independent and can be applied in
> > any order.
>
> That looks reasonable, but please resend the series with your full
> real name, and also specify the version of LLM you've used to prepare
> the series. I'm uncomfortable taking anonymous commitments.
fyi, this was changed by 816d9992d9ed ("coding-assistants: simplify
attribution") - see latest Documentation/process/coding-assistants.rst.
So now everything is supposed to say only "Assisted-by: LLM". I find
this regrettable - I'm interested in seeing what people are using. Oh
well.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 0/6] bitmap: fix three parsing bugs in bitmap_parse() and bitmap_parselist()
2026-09-25 20:39 ` Andrew Morton
@ 2026-09-26 14:02 ` Yury Norov
0 siblings, 0 replies; 10+ messages in thread
From: Yury Norov @ 2026-09-26 14:02 UTC (permalink / raw)
To: Andrew Morton
Cc: shashank, Yury Norov, Rasmus Villemoes, linux-kernel,
Christian Brauner, Lorenzo Stoakes, Jeff Layton, Jori Koolstra,
Mauro Carvalho Chehab, David Hildenbrand, Jonathan Corbet
+ people from 816d9992d9ed
On Fri, Sep 25, 2026 at 01:39:51PM -0700, Andrew Morton wrote:
> On Fri, 25 Sep 2026 13:05:06 -0400 Yury Norov <ynorov@nvidia.com> wrote:
...
> > That looks reasonable, but please resend the series with your full
> > real name, and also specify the version of LLM you've used to prepare
> > the series. I'm uncomfortable taking anonymous commitments.
>
> fyi, this was changed by 816d9992d9ed ("coding-assistants: simplify
> attribution") - see latest Documentation/process/coding-assistants.rst.
>
> So now everything is supposed to say only "Assisted-by: LLM". I find
> this regrettable - I'm interested in seeing what people are using. Oh
> well.
Huh... The commit says: "provides free advertising to proprietary
software companies", and that makes no sense to me. My email does
exactly the same thing, together with the emails of the vast
majority of the community.
Can we please somehow revert this "simplification"? If people use
some wonder tool, and it helps - I want to know the latest best
practices. I want to know MORE rather than LESS.
Thanks,
Yury
^ permalink raw reply [flat|nested] 10+ messages in thread