--- /dev/null
+From 4ed886b187f47447ad559619c48c086f432d2b77 Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao@kernel.org>
+Date: Tue, 7 May 2024 11:38:47 +0800
+Subject: f2fs: check validation of fault attrs in f2fs_build_fault_attr()
+
+From: Chao Yu <chao@kernel.org>
+
+commit 4ed886b187f47447ad559619c48c086f432d2b77 upstream.
+
+- It missed to check validation of fault attrs in parse_options(),
+let's fix to add check condition in f2fs_build_fault_attr().
+- Use f2fs_build_fault_attr() in __sbi_store() to clean up code.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Cliff Liu <donghua.liu@windriver.com>
+Signed-off-by: He Zhe <Zhe.He@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/f2fs.h | 12 ++++++++----
+ fs/f2fs/super.c | 27 ++++++++++++++++++++-------
+ fs/f2fs/sysfs.c | 14 ++++++++++----
+ 3 files changed, 38 insertions(+), 15 deletions(-)
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -64,7 +64,7 @@ enum {
+
+ struct f2fs_fault_info {
+ atomic_t inject_ops;
+- unsigned int inject_rate;
++ int inject_rate;
+ unsigned int inject_type;
+ };
+
+@@ -4373,10 +4373,14 @@ static inline bool f2fs_need_verity(cons
+ }
+
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+-extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
+- unsigned int type);
++extern int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate,
++ unsigned long type);
+ #else
+-#define f2fs_build_fault_attr(sbi, rate, type) do { } while (0)
++static int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate,
++ unsigned long type)
++{
++ return 0;
++}
+ #endif
+
+ static inline bool is_journalled_quota(struct f2fs_sb_info *sbi)
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -61,21 +61,31 @@ const char *f2fs_fault_name[FAULT_MAX] =
+ [FAULT_DQUOT_INIT] = "dquot initialize",
+ };
+
+-void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
+- unsigned int type)
++int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate,
++ unsigned long type)
+ {
+ struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
+
+ if (rate) {
++ if (rate > INT_MAX)
++ return -EINVAL;
+ atomic_set(&ffi->inject_ops, 0);
+- ffi->inject_rate = rate;
++ ffi->inject_rate = (int)rate;
+ }
+
+- if (type)
+- ffi->inject_type = type;
++ if (type) {
++ if (type >= BIT(FAULT_MAX))
++ return -EINVAL;
++ ffi->inject_type = (unsigned int)type;
++ }
+
+ if (!rate && !type)
+ memset(ffi, 0, sizeof(struct f2fs_fault_info));
++ else
++ f2fs_info(sbi,
++ "build fault injection attr: rate: %lu, type: 0x%lx",
++ rate, type);
++ return 0;
+ }
+ #endif
+
+@@ -901,14 +911,17 @@ static int parse_options(struct super_bl
+ case Opt_fault_injection:
+ if (args->from && match_int(args, &arg))
+ return -EINVAL;
+- f2fs_build_fault_attr(sbi, arg, F2FS_ALL_FAULT_TYPE);
++ if (f2fs_build_fault_attr(sbi, arg,
++ F2FS_ALL_FAULT_TYPE))
++ return -EINVAL;
+ set_opt(sbi, FAULT_INJECTION);
+ break;
+
+ case Opt_fault_type:
+ if (args->from && match_int(args, &arg))
+ return -EINVAL;
+- f2fs_build_fault_attr(sbi, 0, arg);
++ if (f2fs_build_fault_attr(sbi, 0, arg))
++ return -EINVAL;
+ set_opt(sbi, FAULT_INJECTION);
+ break;
+ #else
+--- a/fs/f2fs/sysfs.c
++++ b/fs/f2fs/sysfs.c
+@@ -407,10 +407,16 @@ out:
+ if (ret < 0)
+ return ret;
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+- if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX))
+- return -EINVAL;
+- if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX)
+- return -EINVAL;
++ if (a->struct_type == FAULT_INFO_TYPE) {
++ if (f2fs_build_fault_attr(sbi, 0, t))
++ return -EINVAL;
++ return count;
++ }
++ if (a->struct_type == FAULT_INFO_RATE) {
++ if (f2fs_build_fault_attr(sbi, t, 0))
++ return -EINVAL;
++ return count;
++ }
+ #endif
+ if (a->struct_type == RESERVED_BLOCKS) {
+ spin_lock(&sbi->stat_lock);