forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									3735c5225b
								
							
						
					
					
						commit
						e9bc360b10
					
				
					 1 changed files with 26 additions and 2 deletions
				
			
		|  | @ -1,7 +1,7 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0-only
 | // SPDX-License-Identifier: GPL-2.0-only
 | ||||||
| #include <linux/kernel.h> | #include <linux/kernel.h> | ||||||
| #include <linux/init.h> | #include <linux/init.h> | ||||||
| #include <linux/random.h> | #include <linux/prandom.h> | ||||||
| #include <linux/debugfs.h> | #include <linux/debugfs.h> | ||||||
| #include <linux/sched.h> | #include <linux/sched.h> | ||||||
| #include <linux/stat.h> | #include <linux/stat.h> | ||||||
|  | @ -12,6 +12,24 @@ | ||||||
| #include <linux/stacktrace.h> | #include <linux/stacktrace.h> | ||||||
| #include <linux/fault-inject.h> | #include <linux/fault-inject.h> | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * The should_fail() functions use prandom instead of the normal Linux RNG | ||||||
|  |  * since they don't need cryptographically secure random numbers. | ||||||
|  |  */ | ||||||
|  | static DEFINE_PER_CPU(struct rnd_state, fault_rnd_state); | ||||||
|  | 
 | ||||||
|  | static u32 fault_prandom_u32_below_100(void) | ||||||
|  | { | ||||||
|  | 	struct rnd_state *state; | ||||||
|  | 	u32 res; | ||||||
|  | 
 | ||||||
|  | 	state = &get_cpu_var(fault_rnd_state); | ||||||
|  | 	res = prandom_u32_state(state); | ||||||
|  | 	put_cpu_var(fault_rnd_state); | ||||||
|  | 
 | ||||||
|  | 	return res % 100; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * setup_fault_attr() is a helper function for various __setup handlers, so it |  * setup_fault_attr() is a helper function for various __setup handlers, so it | ||||||
|  * returns 0 on error, because that is what __setup handlers do. |  * returns 0 on error, because that is what __setup handlers do. | ||||||
|  | @ -31,6 +49,8 @@ int setup_fault_attr(struct fault_attr *attr, char *str) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	prandom_init_once(&fault_rnd_state); | ||||||
|  | 
 | ||||||
| 	attr->probability = probability; | 	attr->probability = probability; | ||||||
| 	attr->interval = interval; | 	attr->interval = interval; | ||||||
| 	atomic_set(&attr->times, times); | 	atomic_set(&attr->times, times); | ||||||
|  | @ -146,7 +166,7 @@ bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags) | ||||||
| 			return false; | 			return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (attr->probability <= get_random_u32_below(100)) | 	if (attr->probability <= fault_prandom_u32_below_100()) | ||||||
| 		return false; | 		return false; | ||||||
| 
 | 
 | ||||||
| fail: | fail: | ||||||
|  | @ -219,6 +239,8 @@ struct dentry *fault_create_debugfs_attr(const char *name, | ||||||
| 	if (IS_ERR(dir)) | 	if (IS_ERR(dir)) | ||||||
| 		return dir; | 		return dir; | ||||||
| 
 | 
 | ||||||
|  | 	prandom_init_once(&fault_rnd_state); | ||||||
|  | 
 | ||||||
| 	debugfs_create_ul("probability", mode, dir, &attr->probability); | 	debugfs_create_ul("probability", mode, dir, &attr->probability); | ||||||
| 	debugfs_create_ul("interval", mode, dir, &attr->interval); | 	debugfs_create_ul("interval", mode, dir, &attr->interval); | ||||||
| 	debugfs_create_atomic_t("times", mode, dir, &attr->times); | 	debugfs_create_atomic_t("times", mode, dir, &attr->times); | ||||||
|  | @ -431,6 +453,8 @@ static const struct config_item_type fault_config_type = { | ||||||
| 
 | 
 | ||||||
| void fault_config_init(struct fault_config *config, const char *name) | void fault_config_init(struct fault_config *config, const char *name) | ||||||
| { | { | ||||||
|  | 	prandom_init_once(&fault_rnd_state); | ||||||
|  | 
 | ||||||
| 	config_group_init_type_name(&config->group, name, &fault_config_type); | 	config_group_init_type_name(&config->group, name, &fault_config_type); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(fault_config_init); | EXPORT_SYMBOL_GPL(fault_config_init); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Akinobu Mita
						Akinobu Mita