From eb2c288ae12edd6e8cee7497847f9e81dfd9a4cc Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 20 Apr 2026 12:35:48 +0200 Subject: [PATCH] llc-coloring: improve checking while parsing We can easily avoid the risk of wrapping UINT_MAX <-> 0 by applying a check against the compile-time-constant maximum number of colors. Additionally the overflow checks suffered from an off-by-1, as the parsed ranges are inclusive (e.g. end == start being possible, requiring 1 array slot, while availability of 0 slots was checked in that case). Fixes: 6cdea3444eaf ("xen/arm: add Dom0 cache coloring support") Reported-by: Mykola Kvach Reported-by: Kamil Frankowicz Signed-off-by: Jan Beulich Acked-by: Andrew Cooper xen/common: llc-coloring: Fix off-by-one in parse_color_config() The check uses (*num_colors + (end - start + 1)) >= max_num_colors, which rejects a configuration where exactly max_num_colors colors are specified. For example, if max_num_colors is 4 and *num_colors is 0, a range "0-3" gives (end - start + 1) = 4, and (0 + 4) >= 4 is true, incorrectly returning -EINVAL. Fix this by switching the overflow condition to the state before commit cba8a584de17 that regressed the behavior (i.e. don't add 1). Fixes: cba8a584de17 ("llc-coloring: improve checking while parsing") Signed-off-by: Michal Orzel Reviewed-by: Luca Fancellu master commit: cba8a584de171c8c4510709c2edc9f1cf86b21ab master date: 2026-04-07 13:52:44 +0200 master commit: dc28f531e6a29a6fdd58f24073dfb48af06b8334 master date: 2026-04-10 12:14:05 +0200 --- xen/common/llc-coloring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/common/llc-coloring.c b/xen/common/llc-coloring.c index a572f77a09..778092fe1f 100644 --- a/xen/common/llc-coloring.c +++ b/xen/common/llc-coloring.c @@ -76,7 +76,8 @@ static int __init parse_color_config(const char *buf, unsigned int colors[], else /* Single value */ end = start; - if ( start > end || (end - start) > (UINT_MAX - *num_colors) || + if ( end >= NR_LLC_COLORS || start > end || + (end - start) >= (UINT_MAX - *num_colors) || (*num_colors + (end - start)) >= max_num_colors ) return -EINVAL;