From: Rio Date: Sun, 22 Feb 2026 14:08:04 +0000 (+0530) Subject: kernel/panic: allocate taint string buffer dynamically X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9dff0d0d11ce9aeebdd52ecf1469895e336c87e;p=thirdparty%2Fkernel%2Fstable.git kernel/panic: allocate taint string buffer dynamically The buffer used to hold the taint string is statically allocated, which requires updating whenever a new taint flag is added. Instead, allocate the exact required length at boot once the allocator is available in an init function. The allocation sums the string lengths in taint_flags[], along with space for separators and formatting. print_tainted() is switched to use this dynamically allocated buffer. If allocation fails, print_tainted() warns about the failure and continues to use the original static buffer as a fallback. Link: https://lkml.kernel.org/r/20260222140804.22225-1-rioo.tsukatsukii@gmail.com Signed-off-by: Rio Cc: Joel Granados Cc: Petr Mladek Cc: Wang Jinchao Signed-off-by: Andrew Morton --- diff --git a/kernel/panic.c b/kernel/panic.c index 75368738d32d..5d498ff8a18b 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -802,7 +802,7 @@ EXPORT_SYMBOL(panic); * small shell script that prints the TAINT_FLAGS_COUNT bits of * /proc/sys/kernel/tainted. * - * Also, update TAINT_BUF_MAX below. + * Also, update INIT_TAINT_BUF_MAX below. */ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = { TAINT_FLAG(PROPRIETARY_MODULE, 'P', 'G'), @@ -856,17 +856,58 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose) } } -/* 350 can accommodate all taint flags in verbose mode, with some headroom */ -#define TAINT_BUF_MAX 350 +/* The initial buffer can accommodate all taint flags in verbose + * mode, with some headroom. Once the allocator is available, the + * exact size is allocated dynamically; the initial buffer remains + * as a fallback if allocation fails. + * + * The verbose taint string currently requires up to 327 characters. + */ +#define INIT_TAINT_BUF_MAX 350 + +static char init_taint_buf[INIT_TAINT_BUF_MAX]; +static char *taint_buf = init_taint_buf; +static size_t taint_buf_size = INIT_TAINT_BUF_MAX; + +static __init int alloc_taint_buf(void) +{ + int i; + char *buf; + size_t size = 0; + + size += sizeof("Tainted: ") - 1; + for (i = 0; i < TAINT_FLAGS_COUNT; i++) { + size += 2; /* For ", " */ + size += 4; /* For "[%c]=" */ + size += strlen(taint_flags[i].desc); + } + + size += 1; /* For NULL terminator */ + + buf = kmalloc(size, GFP_KERNEL); + + if (!buf) { + /* Allocation may fail; this warning explains possibly + * truncated taint strings + */ + pr_warn_once("taint string buffer allocation failed, using fallback buffer\n"); + return 0; + } + + taint_buf = buf; + taint_buf_size = size; + + return 0; +} +postcore_initcall(alloc_taint_buf); static const char *_print_tainted(bool verbose) { - static char buf[TAINT_BUF_MAX]; struct seq_buf s; BUILD_BUG_ON(ARRAY_SIZE(taint_flags) != TAINT_FLAGS_COUNT); - seq_buf_init(&s, buf, sizeof(buf)); + seq_buf_init(&s, taint_buf, taint_buf_size); print_tainted_seq(&s, verbose);