]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 7 Feb 2023 12:41:30 +0000 (13:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 7 Feb 2023 12:41:30 +0000 (13:41 +0100)
added patches:
bpf-skip-invalid-kfunc-call-in-backtrack_insn.patch
f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch
f2fs-initialize-locks-earlier-in-f2fs_fill_super.patch
fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch
fs-ntfs3-validate-attribute-data-and-valid-sizes.patch
gfs2-always-check-inode-size-of-inline-inodes.patch
gfs2-cosmetic-gfs2_dinode_-in-out-cleanup.patch
ovl-use-buf-flexible-array-for-memcpy-destination.patch
wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch

queue-6.1/bpf-skip-invalid-kfunc-call-in-backtrack_insn.patch [new file with mode: 0644]
queue-6.1/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch [new file with mode: 0644]
queue-6.1/f2fs-initialize-locks-earlier-in-f2fs_fill_super.patch [new file with mode: 0644]
queue-6.1/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch [new file with mode: 0644]
queue-6.1/fs-ntfs3-validate-attribute-data-and-valid-sizes.patch [new file with mode: 0644]
queue-6.1/gfs2-always-check-inode-size-of-inline-inodes.patch [new file with mode: 0644]
queue-6.1/gfs2-cosmetic-gfs2_dinode_-in-out-cleanup.patch [new file with mode: 0644]
queue-6.1/ovl-use-buf-flexible-array-for-memcpy-destination.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch [new file with mode: 0644]

diff --git a/queue-6.1/bpf-skip-invalid-kfunc-call-in-backtrack_insn.patch b/queue-6.1/bpf-skip-invalid-kfunc-call-in-backtrack_insn.patch
new file mode 100644 (file)
index 0000000..7e3c652
--- /dev/null
@@ -0,0 +1,55 @@
+From d3178e8a434b58678d99257c0387810a24042fb6 Mon Sep 17 00:00:00 2001
+From: Hao Sun <sunhao.th@gmail.com>
+Date: Wed, 4 Jan 2023 09:47:09 +0800
+Subject: bpf: Skip invalid kfunc call in backtrack_insn
+
+From: Hao Sun <sunhao.th@gmail.com>
+
+commit d3178e8a434b58678d99257c0387810a24042fb6 upstream.
+
+The verifier skips invalid kfunc call in check_kfunc_call(), which
+would be captured in fixup_kfunc_call() if such insn is not eliminated
+by dead code elimination. However, this can lead to the following
+warning in backtrack_insn(), also see [1]:
+
+  ------------[ cut here ]------------
+  verifier backtracking bug
+  WARNING: CPU: 6 PID: 8646 at kernel/bpf/verifier.c:2756 backtrack_insn
+  kernel/bpf/verifier.c:2756
+       __mark_chain_precision kernel/bpf/verifier.c:3065
+       mark_chain_precision kernel/bpf/verifier.c:3165
+       adjust_reg_min_max_vals kernel/bpf/verifier.c:10715
+       check_alu_op kernel/bpf/verifier.c:10928
+       do_check kernel/bpf/verifier.c:13821 [inline]
+       do_check_common kernel/bpf/verifier.c:16289
+  [...]
+
+So make backtracking conservative with this by returning ENOTSUPP.
+
+  [1] https://lore.kernel.org/bpf/CACkBjsaXNceR8ZjkLG=dT3P=4A8SBsg0Z5h5PWLryF5=ghKq=g@mail.gmail.com/
+
+Reported-by: syzbot+4da3ff23081bafe74fc2@syzkaller.appspotmail.com
+Signed-off-by: Hao Sun <sunhao.th@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20230104014709.9375-1-sunhao.th@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/verifier.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2664,6 +2664,12 @@ static int backtrack_insn(struct bpf_ver
+               if (opcode == BPF_CALL) {
+                       if (insn->src_reg == BPF_PSEUDO_CALL)
+                               return -ENOTSUPP;
++                      /* kfunc with imm==0 is invalid and fixup_kfunc_call will
++                       * catch this error later. Make backtracking conservative
++                       * with ENOTSUPP.
++                       */
++                      if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && insn->imm == 0)
++                              return -ENOTSUPP;
+                       /* regular helper call sets R0 */
+                       *reg_mask &= ~1;
+                       if (*reg_mask & 0x3f) {
diff --git a/queue-6.1/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch b/queue-6.1/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch
new file mode 100644 (file)
index 0000000..b671931
--- /dev/null
@@ -0,0 +1,95 @@
+From d3b7b4afd6b2c344eabf9cc26b8bfa903c164c7c Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao@kernel.org>
+Date: Tue, 15 Nov 2022 00:08:47 +0800
+Subject: f2fs: fix to do sanity check on i_extra_isize in is_alive()
+
+From: Chao Yu <chao@kernel.org>
+
+commit d3b7b4afd6b2c344eabf9cc26b8bfa903c164c7c upstream.
+
+syzbot found a f2fs bug:
+
+BUG: KASAN: slab-out-of-bounds in data_blkaddr fs/f2fs/f2fs.h:2891 [inline]
+BUG: KASAN: slab-out-of-bounds in is_alive fs/f2fs/gc.c:1117 [inline]
+BUG: KASAN: slab-out-of-bounds in gc_data_segment fs/f2fs/gc.c:1520 [inline]
+BUG: KASAN: slab-out-of-bounds in do_garbage_collect+0x386a/0x3df0 fs/f2fs/gc.c:1734
+Read of size 4 at addr ffff888076557568 by task kworker/u4:3/52
+
+CPU: 1 PID: 52 Comm: kworker/u4:3 Not tainted 6.1.0-rc4-syzkaller-00362-gfef7fd48922d #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+Workqueue: writeback wb_workfn (flush-7:0)
+Call Trace:
+<TASK>
+__dump_stack lib/dump_stack.c:88 [inline]
+dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
+print_address_description mm/kasan/report.c:284 [inline]
+print_report+0x15e/0x45d mm/kasan/report.c:395
+kasan_report+0xbb/0x1f0 mm/kasan/report.c:495
+data_blkaddr fs/f2fs/f2fs.h:2891 [inline]
+is_alive fs/f2fs/gc.c:1117 [inline]
+gc_data_segment fs/f2fs/gc.c:1520 [inline]
+do_garbage_collect+0x386a/0x3df0 fs/f2fs/gc.c:1734
+f2fs_gc+0x88c/0x20a0 fs/f2fs/gc.c:1831
+f2fs_balance_fs+0x544/0x6b0 fs/f2fs/segment.c:410
+f2fs_write_inode+0x57e/0xe20 fs/f2fs/inode.c:753
+write_inode fs/fs-writeback.c:1440 [inline]
+__writeback_single_inode+0xcfc/0x1440 fs/fs-writeback.c:1652
+writeback_sb_inodes+0x54d/0xf90 fs/fs-writeback.c:1870
+wb_writeback+0x2c5/0xd70 fs/fs-writeback.c:2044
+wb_do_writeback fs/fs-writeback.c:2187 [inline]
+wb_workfn+0x2dc/0x12f0 fs/fs-writeback.c:2227
+process_one_work+0x9bf/0x1710 kernel/workqueue.c:2289
+worker_thread+0x665/0x1080 kernel/workqueue.c:2436
+kthread+0x2e4/0x3a0 kernel/kthread.c:376
+ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306
+
+The root cause is that we forgot to do sanity check on .i_extra_isize
+in below path, result in accessing invalid address later, fix it.
+- gc_data_segment
+ - is_alive
+  - data_blkaddr
+   - offset_in_addr
+
+Reported-by: syzbot+f8f3dfa4abc489e768a1@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/linux-f2fs-devel/0000000000003cb3c405ed5c17f9@google.com/T/#u
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/gc.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1078,7 +1078,7 @@ static bool is_alive(struct f2fs_sb_info
+ {
+       struct page *node_page;
+       nid_t nid;
+-      unsigned int ofs_in_node, max_addrs;
++      unsigned int ofs_in_node, max_addrs, base;
+       block_t source_blkaddr;
+       nid = le32_to_cpu(sum->nid);
+@@ -1104,11 +1104,17 @@ static bool is_alive(struct f2fs_sb_info
+               return false;
+       }
+-      max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
+-                                              DEF_ADDRS_PER_BLOCK;
+-      if (ofs_in_node >= max_addrs) {
+-              f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
+-                      ofs_in_node, dni->ino, dni->nid, max_addrs);
++      if (IS_INODE(node_page)) {
++              base = offset_in_addr(F2FS_INODE(node_page));
++              max_addrs = DEF_ADDRS_PER_INODE;
++      } else {
++              base = 0;
++              max_addrs = DEF_ADDRS_PER_BLOCK;
++      }
++
++      if (base + ofs_in_node >= max_addrs) {
++              f2fs_err(sbi, "Inconsistent blkaddr offset: base:%u, ofs_in_node:%u, max:%u, ino:%u, nid:%u",
++                      base, ofs_in_node, max_addrs, dni->ino, dni->nid);
+               f2fs_put_page(node_page, 1);
+               return false;
+       }
diff --git a/queue-6.1/f2fs-initialize-locks-earlier-in-f2fs_fill_super.patch b/queue-6.1/f2fs-initialize-locks-earlier-in-f2fs_fill_super.patch
new file mode 100644 (file)
index 0000000..c6e011d
--- /dev/null
@@ -0,0 +1,102 @@
+From 92b4cf5b48955a4bdd15fe4e2067db8ebd87f04c Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Wed, 9 Nov 2022 07:04:42 +0900
+Subject: f2fs: initialize locks earlier in f2fs_fill_super()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 92b4cf5b48955a4bdd15fe4e2067db8ebd87f04c upstream.
+
+syzbot is reporting lockdep warning at f2fs_handle_error() [1], for
+spin_lock(&sbi->error_lock) is called before spin_lock_init() is called.
+For safe locking in error handling, move initialization of locks (and
+obvious structures) in f2fs_fill_super() to immediately after memory
+allocation.
+
+Link: https://syzkaller.appspot.com/bug?extid=40642be9b7e0bb28e0df [1]
+Reported-by: syzbot <syzbot+40642be9b7e0bb28e0df@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Tested-by: syzbot <syzbot+40642be9b7e0bb28e0df@syzkaller.appspotmail.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/super.c |   38 ++++++++++++++++++++------------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4095,6 +4095,24 @@ try_onemore:
+       sbi->sb = sb;
++      /* initialize locks within allocated memory */
++      init_f2fs_rwsem(&sbi->gc_lock);
++      mutex_init(&sbi->writepages);
++      init_f2fs_rwsem(&sbi->cp_global_sem);
++      init_f2fs_rwsem(&sbi->node_write);
++      init_f2fs_rwsem(&sbi->node_change);
++      spin_lock_init(&sbi->stat_lock);
++      init_f2fs_rwsem(&sbi->cp_rwsem);
++      init_f2fs_rwsem(&sbi->quota_sem);
++      init_waitqueue_head(&sbi->cp_wait);
++      spin_lock_init(&sbi->error_lock);
++
++      for (i = 0; i < NR_INODE_TYPE; i++) {
++              INIT_LIST_HEAD(&sbi->inode_list[i]);
++              spin_lock_init(&sbi->inode_lock[i]);
++      }
++      mutex_init(&sbi->flush_lock);
++
+       /* Load the checksum driver */
+       sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
+       if (IS_ERR(sbi->s_chksum_driver)) {
+@@ -4118,6 +4136,8 @@ try_onemore:
+       sb->s_fs_info = sbi;
+       sbi->raw_super = raw_super;
++      memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);
++
+       /* precompute checksum seed for metadata */
+       if (f2fs_sb_has_inode_chksum(sbi))
+               sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
+@@ -4174,26 +4194,14 @@ try_onemore:
+       /* init f2fs-specific super block info */
+       sbi->valid_super_block = valid_super_block;
+-      init_f2fs_rwsem(&sbi->gc_lock);
+-      mutex_init(&sbi->writepages);
+-      init_f2fs_rwsem(&sbi->cp_global_sem);
+-      init_f2fs_rwsem(&sbi->node_write);
+-      init_f2fs_rwsem(&sbi->node_change);
+       /* disallow all the data/node/meta page writes */
+       set_sbi_flag(sbi, SBI_POR_DOING);
+-      spin_lock_init(&sbi->stat_lock);
+       err = f2fs_init_write_merge_io(sbi);
+       if (err)
+               goto free_bio_info;
+-      spin_lock_init(&sbi->error_lock);
+-      memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);
+-
+-      init_f2fs_rwsem(&sbi->cp_rwsem);
+-      init_f2fs_rwsem(&sbi->quota_sem);
+-      init_waitqueue_head(&sbi->cp_wait);
+       init_sb_info(sbi);
+       err = f2fs_init_iostat(sbi);
+@@ -4271,12 +4279,6 @@ try_onemore:
+       limit_reserve_root(sbi);
+       adjust_unusable_cap_perc(sbi);
+-      for (i = 0; i < NR_INODE_TYPE; i++) {
+-              INIT_LIST_HEAD(&sbi->inode_list[i]);
+-              spin_lock_init(&sbi->inode_lock[i]);
+-      }
+-      mutex_init(&sbi->flush_lock);
+-
+       f2fs_init_extent_cache_info(sbi);
+       f2fs_init_ino_entry_info(sbi);
diff --git a/queue-6.1/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch b/queue-6.1/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch
new file mode 100644 (file)
index 0000000..ec1a05a
--- /dev/null
@@ -0,0 +1,160 @@
+From b76449ee75e21acfe9fa4c653d8598f191ed7d68 Mon Sep 17 00:00:00 2001
+From: Dongliang Mu <dzm91@hust.edu.cn>
+Date: Fri, 11 Nov 2022 13:49:49 +0800
+Subject: fbdev: smscufx: fix error handling code in ufx_usb_probe
+
+From: Dongliang Mu <dzm91@hust.edu.cn>
+
+commit b76449ee75e21acfe9fa4c653d8598f191ed7d68 upstream.
+
+The current error handling code in ufx_usb_probe have many unmatching
+issues, e.g., missing ufx_free_usb_list, destroy_modedb label should
+only include framebuffer_release, fb_dealloc_cmap only matches
+fb_alloc_cmap.
+
+My local syzkaller reports a memory leak bug:
+
+memory leak in ufx_usb_probe
+
+BUG: memory leak
+unreferenced object 0xffff88802f879580 (size 128):
+  comm "kworker/0:7", pid 17416, jiffies 4295067474 (age 46.710s)
+  hex dump (first 32 bytes):
+    80 21 7c 2e 80 88 ff ff 18 d0 d0 0c 80 88 ff ff  .!|.............
+    00 d0 d0 0c 80 88 ff ff e0 ff ff ff 0f 00 00 00  ................
+  backtrace:
+    [<ffffffff814c99a0>] kmalloc_trace+0x20/0x90 mm/slab_common.c:1045
+    [<ffffffff824d219c>] kmalloc include/linux/slab.h:553 [inline]
+    [<ffffffff824d219c>] kzalloc include/linux/slab.h:689 [inline]
+    [<ffffffff824d219c>] ufx_alloc_urb_list drivers/video/fbdev/smscufx.c:1873 [inline]
+    [<ffffffff824d219c>] ufx_usb_probe+0x11c/0x15a0 drivers/video/fbdev/smscufx.c:1655
+    [<ffffffff82d17927>] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396
+    [<ffffffff82712f0d>] call_driver_probe drivers/base/dd.c:560 [inline]
+    [<ffffffff82712f0d>] really_probe+0x12d/0x390 drivers/base/dd.c:639
+    [<ffffffff8271322f>] __driver_probe_device+0xbf/0x140 drivers/base/dd.c:778
+    [<ffffffff827132da>] driver_probe_device+0x2a/0x120 drivers/base/dd.c:808
+    [<ffffffff82713c27>] __device_attach_driver+0xf7/0x150 drivers/base/dd.c:936
+    [<ffffffff82710137>] bus_for_each_drv+0xb7/0x100 drivers/base/bus.c:427
+    [<ffffffff827136b5>] __device_attach+0x105/0x2d0 drivers/base/dd.c:1008
+    [<ffffffff82711d36>] bus_probe_device+0xc6/0xe0 drivers/base/bus.c:487
+    [<ffffffff8270e242>] device_add+0x642/0xdc0 drivers/base/core.c:3517
+    [<ffffffff82d14d5f>] usb_set_configuration+0x8ef/0xb80 drivers/usb/core/message.c:2170
+    [<ffffffff82d2576c>] usb_generic_driver_probe+0x8c/0xc0 drivers/usb/core/generic.c:238
+    [<ffffffff82d16ffc>] usb_probe_device+0x5c/0x140 drivers/usb/core/driver.c:293
+    [<ffffffff82712f0d>] call_driver_probe drivers/base/dd.c:560 [inline]
+    [<ffffffff82712f0d>] really_probe+0x12d/0x390 drivers/base/dd.c:639
+    [<ffffffff8271322f>] __driver_probe_device+0xbf/0x140 drivers/base/dd.c:778
+
+Fix this bug by rewriting the error handling code in ufx_usb_probe.
+
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Tested-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/smscufx.c |   46 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 31 insertions(+), 15 deletions(-)
+
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -1622,7 +1622,7 @@ static int ufx_usb_probe(struct usb_inte
+       struct usb_device *usbdev;
+       struct ufx_data *dev;
+       struct fb_info *info;
+-      int retval;
++      int retval = -ENOMEM;
+       u32 id_rev, fpga_rev;
+       /* usb initialization */
+@@ -1654,15 +1654,17 @@ static int ufx_usb_probe(struct usb_inte
+       if (!ufx_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+               dev_err(dev->gdev, "ufx_alloc_urb_list failed\n");
+-              goto e_nomem;
++              goto put_ref;
+       }
+       /* We don't register a new USB class. Our client interface is fbdev */
+       /* allocates framebuffer driver structure, not framebuffer memory */
+       info = framebuffer_alloc(0, &usbdev->dev);
+-      if (!info)
+-              goto e_nomem;
++      if (!info) {
++              dev_err(dev->gdev, "framebuffer_alloc failed\n");
++              goto free_urb_list;
++      }
+       dev->info = info;
+       info->par = dev;
+@@ -1705,22 +1707,34 @@ static int ufx_usb_probe(struct usb_inte
+       check_warn_goto_error(retval, "unable to find common mode for display and adapter");
+       retval = ufx_reg_set_bits(dev, 0x4000, 0x00000001);
+-      check_warn_goto_error(retval, "error %d enabling graphics engine", retval);
++      if (retval < 0) {
++              dev_err(dev->gdev, "error %d enabling graphics engine", retval);
++              goto setup_modes;
++      }
+       /* ready to begin using device */
+       atomic_set(&dev->usb_active, 1);
+       dev_dbg(dev->gdev, "checking var");
+       retval = ufx_ops_check_var(&info->var, info);
+-      check_warn_goto_error(retval, "error %d ufx_ops_check_var", retval);
++      if (retval < 0) {
++              dev_err(dev->gdev, "error %d ufx_ops_check_var", retval);
++              goto reset_active;
++      }
+       dev_dbg(dev->gdev, "setting par");
+       retval = ufx_ops_set_par(info);
+-      check_warn_goto_error(retval, "error %d ufx_ops_set_par", retval);
++      if (retval < 0) {
++              dev_err(dev->gdev, "error %d ufx_ops_set_par", retval);
++              goto reset_active;
++      }
+       dev_dbg(dev->gdev, "registering framebuffer");
+       retval = register_framebuffer(info);
+-      check_warn_goto_error(retval, "error %d register_framebuffer", retval);
++      if (retval < 0) {
++              dev_err(dev->gdev, "error %d register_framebuffer", retval);
++              goto reset_active;
++      }
+       dev_info(dev->gdev, "SMSC UDX USB device /dev/fb%d attached. %dx%d resolution."
+               " Using %dK framebuffer memory\n", info->node,
+@@ -1728,21 +1742,23 @@ static int ufx_usb_probe(struct usb_inte
+       return 0;
+-error:
+-      fb_dealloc_cmap(&info->cmap);
+-destroy_modedb:
++reset_active:
++      atomic_set(&dev->usb_active, 0);
++setup_modes:
+       fb_destroy_modedb(info->monspecs.modedb);
+       vfree(info->screen_base);
+       fb_destroy_modelist(&info->modelist);
++error:
++      fb_dealloc_cmap(&info->cmap);
++destroy_modedb:
+       framebuffer_release(info);
++free_urb_list:
++      if (dev->urbs.count > 0)
++              ufx_free_urb_list(dev);
+ put_ref:
+       kref_put(&dev->kref, ufx_free); /* ref for framebuffer */
+       kref_put(&dev->kref, ufx_free); /* last ref from kref_init */
+       return retval;
+-
+-e_nomem:
+-      retval = -ENOMEM;
+-      goto put_ref;
+ }
+ static void ufx_usb_disconnect(struct usb_interface *interface)
diff --git a/queue-6.1/fs-ntfs3-validate-attribute-data-and-valid-sizes.patch b/queue-6.1/fs-ntfs3-validate-attribute-data-and-valid-sizes.patch
new file mode 100644 (file)
index 0000000..819322f
--- /dev/null
@@ -0,0 +1,46 @@
+From 019d22eb0eb707fc099e6e8fad9b3933236a06d0 Mon Sep 17 00:00:00 2001
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+Date: Tue, 4 Oct 2022 08:45:02 +0530
+Subject: fs/ntfs3: Validate attribute data and valid sizes
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+commit 019d22eb0eb707fc099e6e8fad9b3933236a06d0 upstream.
+
+The data_size and valid_size fields of non resident attributes should be
+less than the its alloc_size field, but this is not checked in
+ntfs_read_mft function.
+
+Syzbot reports a allocation order warning due to a large unchecked value
+of data_size getting assigned to inode->i_size which is then passed to
+kcalloc.
+
+Add sanity check for ensuring that the data_size and valid_size fields
+are not larger than alloc_size field.
+
+Link: https://syzkaller.appspot.com/bug?extid=fa4648a5446460b7b963
+Reported-and-tested-by: syzbot+fa4648a5446460b7b963@syzkaller.appspotmail.com
+Fixes: (82cae269cfa95) fs/ntfs3: Add initialization of super block
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs3/inode.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -132,6 +132,13 @@ next_attr:
+       if (le16_to_cpu(attr->name_off) + attr->name_len > asize)
+               goto out;
++      if (attr->non_res) {
++              t64 = le64_to_cpu(attr->nres.alloc_size);
++              if (le64_to_cpu(attr->nres.data_size) > t64 ||
++                  le64_to_cpu(attr->nres.valid_size) > t64)
++                      goto out;
++      }
++
+       switch (attr->type) {
+       case ATTR_STD:
+               if (attr->non_res ||
diff --git a/queue-6.1/gfs2-always-check-inode-size-of-inline-inodes.patch b/queue-6.1/gfs2-always-check-inode-size-of-inline-inodes.patch
new file mode 100644 (file)
index 0000000..4ffd061
--- /dev/null
@@ -0,0 +1,61 @@
+From 70376c7ff31221f1d21db5611d8209e677781d3a Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruenba@redhat.com>
+Date: Sun, 4 Dec 2022 17:00:04 +0100
+Subject: gfs2: Always check inode size of inline inodes
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+commit 70376c7ff31221f1d21db5611d8209e677781d3a upstream.
+
+Check if the inode size of stuffed (inline) inodes is within the allowed
+range when reading inodes from disk (gfs2_dinode_in()).  This prevents
+us from on-disk corruption.
+
+The two checks in stuffed_readpage() and gfs2_unstuffer_page() that just
+truncate inline data to the maximum allowed size don't actually make
+sense, and they can be removed now as well.
+
+Reported-by: syzbot+7bb81dfa9cda07d9cd9d@syzkaller.appspotmail.com
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/gfs2/aops.c  |    2 --
+ fs/gfs2/bmap.c  |    3 ---
+ fs/gfs2/glops.c |    3 +++
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/fs/gfs2/aops.c
++++ b/fs/gfs2/aops.c
+@@ -427,8 +427,6 @@ static int stuffed_readpage(struct gfs2_
+               return error;
+       kaddr = kmap_atomic(page);
+-      if (dsize > gfs2_max_stuffed_size(ip))
+-              dsize = gfs2_max_stuffed_size(ip);
+       memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
+       memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
+       kunmap_atomic(kaddr);
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -61,9 +61,6 @@ static int gfs2_unstuffer_page(struct gf
+               void *kaddr = kmap(page);
+               u64 dsize = i_size_read(inode);
+  
+-              if (dsize > gfs2_max_stuffed_size(ip))
+-                      dsize = gfs2_max_stuffed_size(ip);
+-
+               memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
+               memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
+               kunmap(page);
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -449,6 +449,9 @@ static int gfs2_dinode_in(struct gfs2_in
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
++      if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip))
++              goto corrupt;
++
+       if (S_ISREG(inode->i_mode))
+               gfs2_set_aops(inode);
diff --git a/queue-6.1/gfs2-cosmetic-gfs2_dinode_-in-out-cleanup.patch b/queue-6.1/gfs2-cosmetic-gfs2_dinode_-in-out-cleanup.patch
new file mode 100644 (file)
index 0000000..9b41cd5
--- /dev/null
@@ -0,0 +1,154 @@
+From 7db354444ad8429e660b0f8145d425285d4f90ff Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruenba@redhat.com>
+Date: Sun, 4 Dec 2022 16:50:41 +0100
+Subject: gfs2: Cosmetic gfs2_dinode_{in,out} cleanup
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+commit 7db354444ad8429e660b0f8145d425285d4f90ff upstream.
+
+In each of the two functions, add an inode variable that points to
+&ip->i_inode and use that throughout the rest of the function.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/gfs2/glops.c |   41 +++++++++++++++++++++--------------------
+ fs/gfs2/super.c |   27 ++++++++++++++-------------
+ 2 files changed, 35 insertions(+), 33 deletions(-)
+
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -397,38 +397,39 @@ static int gfs2_dinode_in(struct gfs2_in
+       struct timespec64 atime;
+       u16 height, depth;
+       umode_t mode = be32_to_cpu(str->di_mode);
+-      bool is_new = ip->i_inode.i_state & I_NEW;
++      struct inode *inode = &ip->i_inode;
++      bool is_new = inode->i_state & I_NEW;
+       if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
+               goto corrupt;
+-      if (unlikely(!is_new && inode_wrong_type(&ip->i_inode, mode)))
++      if (unlikely(!is_new && inode_wrong_type(inode, mode)))
+               goto corrupt;
+       ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
+-      ip->i_inode.i_mode = mode;
++      inode->i_mode = mode;
+       if (is_new) {
+-              ip->i_inode.i_rdev = 0;
++              inode->i_rdev = 0;
+               switch (mode & S_IFMT) {
+               case S_IFBLK:
+               case S_IFCHR:
+-                      ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
+-                                                 be32_to_cpu(str->di_minor));
++                      inode->i_rdev = MKDEV(be32_to_cpu(str->di_major),
++                                            be32_to_cpu(str->di_minor));
+                       break;
+               }
+       }
+-      i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
+-      i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
+-      set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
+-      i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
+-      gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
++      i_uid_write(inode, be32_to_cpu(str->di_uid));
++      i_gid_write(inode, be32_to_cpu(str->di_gid));
++      set_nlink(inode, be32_to_cpu(str->di_nlink));
++      i_size_write(inode, be64_to_cpu(str->di_size));
++      gfs2_set_inode_blocks(inode, be64_to_cpu(str->di_blocks));
+       atime.tv_sec = be64_to_cpu(str->di_atime);
+       atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
+-      if (timespec64_compare(&ip->i_inode.i_atime, &atime) < 0)
+-              ip->i_inode.i_atime = atime;
+-      ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
+-      ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
+-      ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
+-      ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
++      if (timespec64_compare(&inode->i_atime, &atime) < 0)
++              inode->i_atime = atime;
++      inode->i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
++      inode->i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
++      inode->i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
++      inode->i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
+       ip->i_goal = be64_to_cpu(str->di_goal_meta);
+       ip->i_generation = be64_to_cpu(str->di_generation);
+@@ -436,7 +437,7 @@ static int gfs2_dinode_in(struct gfs2_in
+       ip->i_diskflags = be32_to_cpu(str->di_flags);
+       ip->i_eattr = be64_to_cpu(str->di_eattr);
+       /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
+-      gfs2_set_inode_flags(&ip->i_inode);
++      gfs2_set_inode_flags(inode);
+       height = be16_to_cpu(str->di_height);
+       if (unlikely(height > GFS2_MAX_META_HEIGHT))
+               goto corrupt;
+@@ -448,8 +449,8 @@ static int gfs2_dinode_in(struct gfs2_in
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
+-      if (S_ISREG(ip->i_inode.i_mode))
+-              gfs2_set_aops(&ip->i_inode);
++      if (S_ISREG(inode->i_mode))
++              gfs2_set_aops(inode);
+       return 0;
+ corrupt:
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -379,6 +379,7 @@ out:
+ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
+ {
++      const struct inode *inode = &ip->i_inode;
+       struct gfs2_dinode *str = buf;
+       str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
+@@ -386,15 +387,15 @@ void gfs2_dinode_out(const struct gfs2_i
+       str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
+       str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
+       str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
+-      str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
+-      str->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode));
+-      str->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode));
+-      str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
+-      str->di_size = cpu_to_be64(i_size_read(&ip->i_inode));
+-      str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
+-      str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
+-      str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
+-      str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
++      str->di_mode = cpu_to_be32(inode->i_mode);
++      str->di_uid = cpu_to_be32(i_uid_read(inode));
++      str->di_gid = cpu_to_be32(i_gid_read(inode));
++      str->di_nlink = cpu_to_be32(inode->i_nlink);
++      str->di_size = cpu_to_be64(i_size_read(inode));
++      str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(inode));
++      str->di_atime = cpu_to_be64(inode->i_atime.tv_sec);
++      str->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec);
++      str->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec);
+       str->di_goal_meta = cpu_to_be64(ip->i_goal);
+       str->di_goal_data = cpu_to_be64(ip->i_goal);
+@@ -402,16 +403,16 @@ void gfs2_dinode_out(const struct gfs2_i
+       str->di_flags = cpu_to_be32(ip->i_diskflags);
+       str->di_height = cpu_to_be16(ip->i_height);
+-      str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
++      str->di_payload_format = cpu_to_be32(S_ISDIR(inode->i_mode) &&
+                                            !(ip->i_diskflags & GFS2_DIF_EXHASH) ?
+                                            GFS2_FORMAT_DE : 0);
+       str->di_depth = cpu_to_be16(ip->i_depth);
+       str->di_entries = cpu_to_be32(ip->i_entries);
+       str->di_eattr = cpu_to_be64(ip->i_eattr);
+-      str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
+-      str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
+-      str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
++      str->di_atime_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
++      str->di_mtime_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
++      str->di_ctime_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
+ }
+ /**
diff --git a/queue-6.1/ovl-use-buf-flexible-array-for-memcpy-destination.patch b/queue-6.1/ovl-use-buf-flexible-array-for-memcpy-destination.patch
new file mode 100644 (file)
index 0000000..f27a3d0
--- /dev/null
@@ -0,0 +1,49 @@
+From cf8aa9bf97cadf85745506c6a3e244b22c268d63 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Sat, 24 Sep 2022 00:33:15 -0700
+Subject: ovl: Use "buf" flexible array for memcpy() destination
+
+From: Kees Cook <keescook@chromium.org>
+
+commit cf8aa9bf97cadf85745506c6a3e244b22c268d63 upstream.
+
+The "buf" flexible array needs to be the memcpy() destination to avoid
+false positive run-time warning from the recent FORTIFY_SOURCE
+hardening:
+
+  memcpy: detected field-spanning write (size 93) of single field "&fh->fb"
+  at fs/overlayfs/export.c:799 (size 21)
+
+Reported-by: syzbot+9d14351a171d0d1c7955@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/000000000000763a6c05e95a5985@google.com/
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/export.c    |    2 +-
+ fs/overlayfs/overlayfs.h |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/overlayfs/export.c
++++ b/fs/overlayfs/export.c
+@@ -796,7 +796,7 @@ static struct ovl_fh *ovl_fid_to_fh(stru
+               return ERR_PTR(-ENOMEM);
+       /* Copy unaligned inner fh into aligned buffer */
+-      memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
++      memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET);
+       return fh;
+ }
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -108,7 +108,7 @@ struct ovl_fh {
+       u8 padding[3];  /* make sure fb.fid is 32bit aligned */
+       union {
+               struct ovl_fb fb;
+-              u8 buf[0];
++              DECLARE_FLEX_ARRAY(u8, buf);
+       };
+ } __packed;
index 6ccf14ed7f33bf0834784d7d0848b709c1adf3f1..313cd689d73fc23e2e71e142f9a96cfc8fcc6e1f 100644 (file)
@@ -197,3 +197,12 @@ iio-adc-twl6030-enable-measurement-of-vac.patch
 powerpc-64s-radix-fix-crash-with-unaligned-relocated-kernel.patch
 powerpc-64s-fix-local-irq-disable-when-pmis-are-disabled.patch
 powerpc-imc-pmu-revert-nest_init_lock-to-being-a-mutex.patch
+fs-ntfs3-validate-attribute-data-and-valid-sizes.patch
+ovl-use-buf-flexible-array-for-memcpy-destination.patch
+f2fs-initialize-locks-earlier-in-f2fs_fill_super.patch
+fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch
+f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch
+wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch
+gfs2-cosmetic-gfs2_dinode_-in-out-cleanup.patch
+gfs2-always-check-inode-size-of-inline-inodes.patch
+bpf-skip-invalid-kfunc-call-in-backtrack_insn.patch
diff --git a/queue-6.1/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch b/queue-6.1/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch
new file mode 100644 (file)
index 0000000..5b88762
--- /dev/null
@@ -0,0 +1,254 @@
+From 4920ab131b2dbae7464b72bdcac465d070254209 Mon Sep 17 00:00:00 2001
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Date: Wed, 16 Nov 2022 23:29:52 +0900
+Subject: wifi: brcmfmac: Check the count value of channel spec to prevent out-of-bounds reads
+
+From: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+
+commit 4920ab131b2dbae7464b72bdcac465d070254209 upstream.
+
+This patch fixes slab-out-of-bounds reads in brcmfmac that occur in
+brcmf_construct_chaninfo() and brcmf_enable_bw40_2g() when the count
+value of channel specifications provided by the device is greater than
+the length of 'list->element[]', decided by the size of the 'list'
+allocated with kzalloc(). The patch adds checks that make the functions
+free the buffer and return -EINVAL if that is the case. Note that the
+negative return is handled by the caller, brcmf_setup_wiphybands() or
+brcmf_cfg80211_attach().
+
+Found by a modified version of syzkaller.
+
+Crash Report from brcmf_construct_chaninfo():
+==================================================================
+BUG: KASAN: slab-out-of-bounds in brcmf_setup_wiphybands+0x1238/0x1430
+Read of size 4 at addr ffff888115f24600 by task kworker/0:2/1896
+
+CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G        W  O      5.14.0+ #132
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ dump_stack_lvl+0x57/0x7d
+ print_address_description.constprop.0.cold+0x93/0x334
+ kasan_report.cold+0x83/0xdf
+ brcmf_setup_wiphybands+0x1238/0x1430
+ brcmf_cfg80211_attach+0x2118/0x3fd0
+ brcmf_attach+0x389/0xd40
+ brcmf_usb_probe+0x12de/0x1690
+ usb_probe_interface+0x25f/0x710
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_set_configuration+0x984/0x1770
+ usb_generic_driver_probe+0x69/0x90
+ usb_probe_device+0x9c/0x220
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_new_device.cold+0x463/0xf66
+ hub_event+0x10d5/0x3330
+ process_one_work+0x873/0x13e0
+ worker_thread+0x8b/0xd10
+ kthread+0x379/0x450
+ ret_from_fork+0x1f/0x30
+
+Allocated by task 1896:
+ kasan_save_stack+0x1b/0x40
+ __kasan_kmalloc+0x7c/0x90
+ kmem_cache_alloc_trace+0x19e/0x330
+ brcmf_setup_wiphybands+0x290/0x1430
+ brcmf_cfg80211_attach+0x2118/0x3fd0
+ brcmf_attach+0x389/0xd40
+ brcmf_usb_probe+0x12de/0x1690
+ usb_probe_interface+0x25f/0x710
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_set_configuration+0x984/0x1770
+ usb_generic_driver_probe+0x69/0x90
+ usb_probe_device+0x9c/0x220
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_new_device.cold+0x463/0xf66
+ hub_event+0x10d5/0x3330
+ process_one_work+0x873/0x13e0
+ worker_thread+0x8b/0xd10
+ kthread+0x379/0x450
+ ret_from_fork+0x1f/0x30
+
+The buggy address belongs to the object at ffff888115f24000
+ which belongs to the cache kmalloc-2k of size 2048
+The buggy address is located 1536 bytes inside of
+ 2048-byte region [ffff888115f24000, ffff888115f24800)
+
+Memory state around the buggy address:
+ ffff888115f24500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ffff888115f24580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+>ffff888115f24600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+                   ^
+ ffff888115f24680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff888115f24700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+==================================================================
+
+Crash Report from brcmf_enable_bw40_2g():
+==================================================================
+BUG: KASAN: slab-out-of-bounds in brcmf_cfg80211_attach+0x3d11/0x3fd0
+Read of size 4 at addr ffff888103787600 by task kworker/0:2/1896
+
+CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G        W  O      5.14.0+ #132
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ dump_stack_lvl+0x57/0x7d
+ print_address_description.constprop.0.cold+0x93/0x334
+ kasan_report.cold+0x83/0xdf
+ brcmf_cfg80211_attach+0x3d11/0x3fd0
+ brcmf_attach+0x389/0xd40
+ brcmf_usb_probe+0x12de/0x1690
+ usb_probe_interface+0x25f/0x710
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_set_configuration+0x984/0x1770
+ usb_generic_driver_probe+0x69/0x90
+ usb_probe_device+0x9c/0x220
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_new_device.cold+0x463/0xf66
+ hub_event+0x10d5/0x3330
+ process_one_work+0x873/0x13e0
+ worker_thread+0x8b/0xd10
+ kthread+0x379/0x450
+ ret_from_fork+0x1f/0x30
+
+Allocated by task 1896:
+ kasan_save_stack+0x1b/0x40
+ __kasan_kmalloc+0x7c/0x90
+ kmem_cache_alloc_trace+0x19e/0x330
+ brcmf_cfg80211_attach+0x3302/0x3fd0
+ brcmf_attach+0x389/0xd40
+ brcmf_usb_probe+0x12de/0x1690
+ usb_probe_interface+0x25f/0x710
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_set_configuration+0x984/0x1770
+ usb_generic_driver_probe+0x69/0x90
+ usb_probe_device+0x9c/0x220
+ really_probe+0x1be/0xa90
+ __driver_probe_device+0x2ab/0x460
+ driver_probe_device+0x49/0x120
+ __device_attach_driver+0x18a/0x250
+ bus_for_each_drv+0x123/0x1a0
+ __device_attach+0x207/0x330
+ bus_probe_device+0x1a2/0x260
+ device_add+0xa61/0x1ce0
+ usb_new_device.cold+0x463/0xf66
+ hub_event+0x10d5/0x3330
+ process_one_work+0x873/0x13e0
+ worker_thread+0x8b/0xd10
+ kthread+0x379/0x450
+ ret_from_fork+0x1f/0x30
+
+The buggy address belongs to the object at ffff888103787000
+ which belongs to the cache kmalloc-2k of size 2048
+The buggy address is located 1536 bytes inside of
+ 2048-byte region [ffff888103787000, ffff888103787800)
+
+Memory state around the buggy address:
+ ffff888103787500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ffff888103787580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+>ffff888103787600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+                   ^
+ ffff888103787680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff888103787700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+==================================================================
+
+Reported-by: Dokyung Song <dokyungs@yonsei.ac.kr>
+Reported-by: Jisoo Jang <jisoo.jang@yonsei.ac.kr>
+Reported-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221116142952.518241-1-linuxlovemin@yonsei.ac.kr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |   17 ++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -91,6 +91,9 @@
+ #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
+       (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
++#define BRCMF_MAX_CHANSPEC_LIST \
++      (BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1)
++
+ static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
+ {
+       if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
+@@ -6556,6 +6559,13 @@ static int brcmf_construct_chaninfo(stru
+                       band->channels[i].flags = IEEE80211_CHAN_DISABLED;
+       total = le32_to_cpu(list->count);
++      if (total > BRCMF_MAX_CHANSPEC_LIST) {
++              bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
++                       total);
++              err = -EINVAL;
++              goto fail_pbuf;
++      }
++
+       for (i = 0; i < total; i++) {
+               ch.chspec = (u16)le32_to_cpu(list->element[i]);
+               cfg->d11inf.decchspec(&ch);
+@@ -6701,6 +6711,13 @@ static int brcmf_enable_bw40_2g(struct b
+               band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
+               list = (struct brcmf_chanspec_list *)pbuf;
+               num_chan = le32_to_cpu(list->count);
++              if (num_chan > BRCMF_MAX_CHANSPEC_LIST) {
++                      bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
++                               num_chan);
++                      kfree(pbuf);
++                      return -EINVAL;
++              }
++
+               for (i = 0; i < num_chan; i++) {
+                       ch.chspec = (u16)le32_to_cpu(list->element[i]);
+                       cfg->d11inf.decchspec(&ch);