[PATCH] taskstats: fix cpumask parsing cutting off the last character

From: Bradley Morgan

Date: Thu Jul 23 2026 - 17:09:22 EST


parse() hands nla_strscpy() len as dstsize, and nla_strscpy() copies
at most dstsize - 1 bytes. When the attr payload comes in without a
trailing NUL, srclen == len >= dstsize and the last character of the
cpumask string gets cut off. Register "0-15" and you are silently
listening on "0-1", exit data for the rest never shows up.

The bug only bites when the sender doesnt NUL terminate the payload;
senders that include the NUL were always fine (srclen gets decremented
for the trailing NUL, so srclen < dstsize). Thats probably why this
survived 20 years. And the policy is NLA_STRING, not NLA_NUL_STRING,
so a payload without the trailing NUL is legit input here.

Skip the kmalloc/nla_strscpy dance entirely and use nla_strdup(),
which already allocates srclen + 1 and terminates. The nla_len()
bounds checks stay as they were.

Fixes: f9fd8914c1ac ("[PATCH] per-task delay accounting taskstats interface: control exit data through cpumasks")
Reported-by: Oleg Deomi <oleg.deomi@xxxxxxxxx>
Closes: https://lore.kernel.org/CAByWkfZ6b1=3H9pwkz-dDQOs9cZaF-HYQ6b9Yb0=Hq2r1Vv_Pw@xxxxxxxxxxxxxx
Cc: Balbir Singh <bsingharora@xxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Bradley Morgan <include@xxxxxxxxx>
---
kernel/taskstats.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index d19bff9..632ca95 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -371,10 +371,9 @@ static int parse(struct nlattr *na, struct cpumask *mask)
return -E2BIG;
if (len < 1)
return -EINVAL;
- data = kmalloc(len, GFP_KERNEL);
+ data = nla_strdup(na, GFP_KERNEL);
if (!data)
return -ENOMEM;
- nla_strscpy(data, na, len);
ret = cpulist_parse(data, mask);
kfree(data);
return ret;
--
2.49.0


I better hope my mail client doesn't break the hell out of this! :)

Thanks!