Re: [BUG] taskstats: REGISTER_CPUMASK silently truncates the last byte of the cpumask string
From: Bradley Morgan
Date: Thu Jul 23 2026 - 19:20:29 EST
On July 24, 2026 12:17:09 AM GMT+01:00, Andrew Morton
<akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>On Thu, 23 Jul 2026 22:11:43 +0100 Bradley Morgan <include@xxxxxxxxx>
>wrote:
>
>>...
>>
>> Hi Andrew, let me be honest, I CBA to do a new thread, here's my
>suggestion
>
>Seems this fooled Sashiko, so no AI review for you!
if you must do ai review! :)
just put it into Gemini, (preferably on a coding agent, not on the app, or
it'll just say complete bullcrap)
>> From: Bradley Morgan <include@xxxxxxxxx>
>> Date: Thu, 23 Jul 2026 21:09:22 +0000
>> Subject: [PATCH] taskstats: fix cpumask parsing cutting off the last
>character
>>
>> 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.
>>
>> ...
>>
>> --- 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;
>
>Nice, thanks, There's a nla_strdup(), who knew?
Heh.
>(nla_strdup() could use kstrdup(), btw?)
ehhh. does it matter? Heh.
Thanks!