Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fault-inject: use prandom where cryptographically secure randomness is not needed

Currently get_random*() is used to determine the probability of fault
injection, but cryptographically secure random numbers are not required.

There is no big problem in using prandom instead of get_random*() to
determine the probability of fault injection, and it also avoids acquiring
a spinlock, which is unsafe in some contexts.

[akpm@linux-foundation.org: tweak and reflow comment]
Link: https://lore.kernel.org/lkml/20241129120939.GG35539@noisy.programming.kicks-ass.net
Link: https://lkml.kernel.org/r/20241208142415.205960-1-akinobu.mita@gmail.com
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Akinobu Mita and committed by
Andrew Morton
e9bc360b 3735c522

+26 -2
+26 -2
lib/fault-inject.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 #include <linux/kernel.h> 3 3 #include <linux/init.h> 4 - #include <linux/random.h> 4 + #include <linux/prandom.h> 5 5 #include <linux/debugfs.h> 6 6 #include <linux/sched.h> 7 7 #include <linux/stat.h> ··· 11 11 #include <linux/interrupt.h> 12 12 #include <linux/stacktrace.h> 13 13 #include <linux/fault-inject.h> 14 + 15 + /* 16 + * The should_fail() functions use prandom instead of the normal Linux RNG 17 + * since they don't need cryptographically secure random numbers. 18 + */ 19 + static DEFINE_PER_CPU(struct rnd_state, fault_rnd_state); 20 + 21 + static u32 fault_prandom_u32_below_100(void) 22 + { 23 + struct rnd_state *state; 24 + u32 res; 25 + 26 + state = &get_cpu_var(fault_rnd_state); 27 + res = prandom_u32_state(state); 28 + put_cpu_var(fault_rnd_state); 29 + 30 + return res % 100; 31 + } 14 32 15 33 /* 16 34 * setup_fault_attr() is a helper function for various __setup handlers, so it ··· 48 30 "FAULT_INJECTION: failed to parse arguments\n"); 49 31 return 0; 50 32 } 33 + 34 + prandom_init_once(&fault_rnd_state); 51 35 52 36 attr->probability = probability; 53 37 attr->interval = interval; ··· 166 146 return false; 167 147 } 168 148 169 - if (attr->probability <= get_random_u32_below(100)) 149 + if (attr->probability <= fault_prandom_u32_below_100()) 170 150 return false; 171 151 172 152 fail: ··· 238 218 dir = debugfs_create_dir(name, parent); 239 219 if (IS_ERR(dir)) 240 220 return dir; 221 + 222 + prandom_init_once(&fault_rnd_state); 241 223 242 224 debugfs_create_ul("probability", mode, dir, &attr->probability); 243 225 debugfs_create_ul("interval", mode, dir, &attr->interval); ··· 453 431 454 432 void fault_config_init(struct fault_config *config, const char *name) 455 433 { 434 + prandom_init_once(&fault_rnd_state); 435 + 456 436 config_group_init_type_name(&config->group, name, &fault_config_type); 457 437 } 458 438 EXPORT_SYMBOL_GPL(fault_config_init);