Thread (3 messages) flat view 3 messages, 2 authors, 9d ago
DORMANTno replies REVIEWED: 31 (31M)

1 review trailer.

[PATCH 5.10.y 2/2] taskstats: fix cpumask parsing cutting off the last character

From: Sasha Levin <sashal@kernel.org>
Date: 2026-09-10 01:17:25
Subsystem: taskstats statistics interface, the rest · Maintainers: Balbir Singh, Linus Torvalds

From: Bradley Morgan <redacted>

[ Upstream commit 1f58a5335cdd14b3fb5f2a5d3763dee1f5cba1d3 ]

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 doesn't 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.

Link: https://lore.kernel.org/EC49FE41-7F5F-41E0-A07A-ABEB8ECA514D@grrlz.net (local)
Fixes: f9fd8914c1ac ("[PATCH] per-task delay accounting taskstats interface: control exit data through cpumasks")
Signed-off-by: Bradley Morgan <redacted>
Reported-by: Oleg Deomi <redacted>
Closes: https://lore.kernel.org/CAByWkfZ6b1=3H9pwkz-dDQOs9cZaF-HYQ6b9Yb0=Hq2r1Vv_Pw@mail.gmail.com (local)
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: <redacted>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Adapted the removal of nla_strscpy() to the older nla_strlcpy() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/taskstats.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index a2d24fb7cf407..ef2c4fea49c86 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -346,10 +346,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_strlcpy(data, na, len);
 	ret = cpulist_parse(data, mask);
 	kfree(data);
 	return ret;
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help