mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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 <rioo.tsukatsukii@gmail.com> Cc: Joel Granados <joel.granados@kernel.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Wang Jinchao <wangjinchao600@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user