From c68153647166af1e9251a8c1bb1d44d0d4dc9155 Mon Sep 17 00:00:00 2001 From: Tj Date: Tue, 30 Jul 2024 11:28:38 +1200 Subject: [PATCH] UBUNTU: SAUCE: arm64: v6.8: cmdline param >= 146 chars kills kernel BugLink: https://bugs.launchpad.net/bugs/2069534 This is v6.8 specific; v6.9 is reported as not affected (due to extensive code refactoring). Commit dc3f5aae0638 reworked how early cmdline CPU feature parsing is done, and converted to using memcmp() in preparation for the move to the pi minimal C standard library. As a result it caused a regression where-by a parameter >= 146 characters on the kernel command line would cause a silent panic with no console clues as to why. It is due to memcmp() in include/linux/fortify-string.h detecting an attempted out-of-bounds read. The cause itself is subtle. arch/arm64/kernel/idreg-override.c::__parse_cmdline() compares the struct aliases entries with each parameter via memcmp(). ... static const struct { char alias[FTR_ALIAS_NAME_LEN]; char feature[FTR_ALIAS_OPTION_LEN]; } aliases[] Each element is 146 characters. When a parameter is also 146 characters the call looks like memcmp(buf, aliases[i].alias, len+1) where len is the equivalent of strlen(buf) and +1 to compare including the trailing NUL. That triggers the fortified memcmp()'s: if (p_size < size || q_size < size) fortify_panic(__func__); where q_size == 146, size == 147 The solution here is to not call memcmp() at all unless the two strings have the same length. Initially reported in Ubuntu (and confirmed to affect Debian and Mainline): https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2069534 Fixes: dc3f5aae0638 ("arm64: idreg-override: Avoid parameq() and parameqn()") Signed-off-by: Tj Signed-off-by: Matthew Ruffell Acked-by: Roxana Nicolescu Acked-by: Manuel Diewald Signed-off-by: Manuel Diewald Signed-off-by: Roxana Nicolescu --- arch/arm64/kernel/idreg-override.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index e30fd9e32ef3..9d2c120f378a 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -308,7 +308,8 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases) match_options(buf); for (i = 0; parse_aliases && i < ARRAY_SIZE(aliases); i++) - if (!memcmp(buf, aliases[i].alias, len + 1)) + if (len == strlen(aliases[i].alias) && + !memcmp(buf, aliases[i].alias, len + 1)) __parse_cmdline(aliases[i].feature, false); } while (1); }