mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01: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:
parent
a75d207916
commit
a9dff0d0d1
|
|
@ -802,7 +802,7 @@ EXPORT_SYMBOL(panic);
|
||||||
* small shell script that prints the TAINT_FLAGS_COUNT bits of
|
* small shell script that prints the TAINT_FLAGS_COUNT bits of
|
||||||
* /proc/sys/kernel/tainted.
|
* /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] = {
|
const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
|
||||||
TAINT_FLAG(PROPRIETARY_MODULE, 'P', 'G'),
|
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 */
|
/* The initial buffer can accommodate all taint flags in verbose
|
||||||
#define TAINT_BUF_MAX 350
|
* 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 const char *_print_tainted(bool verbose)
|
||||||
{
|
{
|
||||||
static char buf[TAINT_BUF_MAX];
|
|
||||||
struct seq_buf s;
|
struct seq_buf s;
|
||||||
|
|
||||||
BUILD_BUG_ON(ARRAY_SIZE(taint_flags) != TAINT_FLAGS_COUNT);
|
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);
|
print_tainted_seq(&s, verbose);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user