]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 7 Feb 2023 12:51:09 +0000 (13:51 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 7 Feb 2023 12:51:09 +0000 (13:51 +0100)
added patches:
f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch
fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch
wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch

queue-5.10/bpf-fix-to-preserve-reg-parent-live-fields-when-copy.patch
queue-5.10/bpf-support-8-byte-scalar-spill-and-refill.patch
queue-5.10/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch [new file with mode: 0644]
queue-5.10/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch [new file with mode: 0644]

index 8d6a898a9036883bc6beb4c5112ab9c0af96fab1..31b01f8ef457a60f5c6cd2bafd39fbf0b49e721e 100644 (file)
@@ -101,14 +101,12 @@ Link: https://lore.kernel.org/r/20230106142214.1040390-2-eddyz87@gmail.com
 Signed-off-by: Alexei Starovoitov <ast@kernel.org>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- kernel/bpf/verifier.c | 25 ++++++++++++++++++-------
+ kernel/bpf/verifier.c |   25 ++++++++++++++++++-------
  1 file changed, 18 insertions(+), 7 deletions(-)
 
-diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
-index e06b84c7b890..7b461a70a0e6 100644
 --- a/kernel/bpf/verifier.c
 +++ b/kernel/bpf/verifier.c
-@@ -2278,13 +2278,24 @@ static bool __is_pointer_value(bool allow_ptr_leaks,
+@@ -2274,13 +2274,24 @@ static bool __is_pointer_value(bool allo
        return reg->type != SCALAR_VALUE;
  }
  
@@ -134,7 +132,7 @@ index e06b84c7b890..7b461a70a0e6 100644
        if (size == BPF_REG_SIZE)
                state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
  
-@@ -2612,7 +2623,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+@@ -2608,7 +2619,7 @@ static int check_stack_read_fixed_off(st
                                 */
                                s32 subreg_def = state->regs[dst_regno].subreg_def;
  
@@ -143,7 +141,7 @@ index e06b84c7b890..7b461a70a0e6 100644
                                state->regs[dst_regno].subreg_def = subreg_def;
                        } else {
                                for (i = 0; i < size; i++) {
-@@ -2639,7 +2650,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+@@ -2635,7 +2646,7 @@ static int check_stack_read_fixed_off(st
  
                if (dst_regno >= 0) {
                        /* restore register state from stack */
@@ -152,7 +150,7 @@ index e06b84c7b890..7b461a70a0e6 100644
                        /* mark reg as written since spilled pointer state likely
                         * has its liveness marks cleared by is_state_visited()
                         * which resets stack/reg liveness for state transitions
-@@ -5900,7 +5911,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
+@@ -5896,7 +5907,7 @@ do_sim:
         */
        if (!ptr_is_dst_reg) {
                tmp = *dst_reg;
@@ -161,7 +159,7 @@ index e06b84c7b890..7b461a70a0e6 100644
        }
        ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1,
                                        env->insn_idx);
-@@ -7154,7 +7165,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
+@@ -7150,7 +7161,7 @@ static int check_alu_op(struct bpf_verif
                                         * to propagate min/max range.
                                         */
                                        src_reg->id = ++env->id_gen;
@@ -170,7 +168,7 @@ index e06b84c7b890..7b461a70a0e6 100644
                                dst_reg->live |= REG_LIVE_WRITTEN;
                                dst_reg->subreg_def = DEF_NOT_SUBREG;
                        } else {
-@@ -7165,7 +7176,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
+@@ -7161,7 +7172,7 @@ static int check_alu_op(struct bpf_verif
                                                insn->src_reg);
                                        return -EACCES;
                                } else if (src_reg->type == SCALAR_VALUE) {
@@ -179,7 +177,7 @@ index e06b84c7b890..7b461a70a0e6 100644
                                        /* Make sure ID is cleared otherwise
                                         * dst_reg min/max could be incorrectly
                                         * propagated into src_reg by find_equal_scalars()
-@@ -7985,7 +7996,7 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate,
+@@ -7981,7 +7992,7 @@ static void find_equal_scalars(struct bp
  
        bpf_for_each_reg_in_vstate(vstate, state, reg, ({
                if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
@@ -188,6 +186,3 @@ index e06b84c7b890..7b461a70a0e6 100644
        }));
  }
  
--- 
-2.39.0
-
index f72b9b5efc04352ce5e2c0aa36175c0d6288c883..d6da1882a44626635d67788cb31198de5dbaa9e2 100644 (file)
@@ -59,14 +59,12 @@ Link: https://lore.kernel.org/bpf/20210922004941.625398-1-kafai@fb.com
 Stable-dep-of: 71f656a50176 ("bpf: Fix to preserve reg parent/live fields when copying range info")
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- kernel/bpf/verifier.c | 67 +++++++++++++++++++++++++++++++++----------
+ kernel/bpf/verifier.c |   67 ++++++++++++++++++++++++++++++++++++++------------
  1 file changed, 52 insertions(+), 15 deletions(-)
 
-diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
-index a6c931fed39b..e06b84c7b890 100644
 --- a/kernel/bpf/verifier.c
 +++ b/kernel/bpf/verifier.c
-@@ -570,6 +570,12 @@ static bool is_spilled_reg(const struct bpf_stack_state *stack)
+@@ -570,6 +570,12 @@ static bool is_spilled_reg(const struct
        return stack->slot_type[BPF_REG_SIZE - 1] == STACK_SPILL;
  }
  
@@ -79,7 +77,7 @@ index a6c931fed39b..e06b84c7b890 100644
  static void print_verifier_state(struct bpf_verifier_env *env,
                                 const struct bpf_func_state *state)
  {
-@@ -2273,15 +2279,21 @@ static bool __is_pointer_value(bool allow_ptr_leaks,
+@@ -2269,15 +2275,21 @@ static bool __is_pointer_value(bool allo
  }
  
  static void save_register_state(struct bpf_func_state *state,
@@ -105,7 +103,7 @@ index a6c931fed39b..e06b84c7b890 100644
  }
  
  /* check_stack_{read,write}_fixed_off functions track spill/fill of registers,
-@@ -2331,7 +2343,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+@@ -2327,7 +2339,7 @@ static int check_stack_write_fixed_off(s
                        env->insn_aux_data[insn_idx].sanitize_stack_spill = true;
        }
  
@@ -114,7 +112,7 @@ index a6c931fed39b..e06b84c7b890 100644
            !register_is_null(reg) && env->bpf_capable) {
                if (dst_reg != BPF_REG_FP) {
                        /* The backtracking logic can only recognize explicit
-@@ -2344,7 +2356,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+@@ -2340,7 +2352,7 @@ static int check_stack_write_fixed_off(s
                        if (err)
                                return err;
                }
@@ -123,7 +121,7 @@ index a6c931fed39b..e06b84c7b890 100644
        } else if (reg && is_spillable_regtype(reg->type)) {
                /* register containing pointer is being spilled into stack */
                if (size != BPF_REG_SIZE) {
-@@ -2356,7 +2368,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+@@ -2352,7 +2364,7 @@ static int check_stack_write_fixed_off(s
                        verbose(env, "cannot spill pointers to stack into stack frame of the caller\n");
                        return -EINVAL;
                }
@@ -132,7 +130,7 @@ index a6c931fed39b..e06b84c7b890 100644
        } else {
                u8 type = STACK_MISC;
  
-@@ -2365,7 +2377,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
+@@ -2361,7 +2373,7 @@ static int check_stack_write_fixed_off(s
                /* Mark slots as STACK_MISC if they belonged to spilled ptr. */
                if (is_spilled_reg(&state->stack[spi]))
                        for (i = 0; i < BPF_REG_SIZE; i++)
@@ -141,7 +139,7 @@ index a6c931fed39b..e06b84c7b890 100644
  
                /* only mark the slot as written if all 8 bytes were written
                 * otherwise read propagation may incorrectly stop too soon
-@@ -2572,23 +2584,50 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+@@ -2568,23 +2580,50 @@ static int check_stack_read_fixed_off(st
        struct bpf_func_state *state = vstate->frame[vstate->curframe];
        int i, slot = -off - 1, spi = slot / BPF_REG_SIZE;
        struct bpf_reg_state *reg;
@@ -196,7 +194,7 @@ index a6c931fed39b..e06b84c7b890 100644
                        return 0;
                }
                for (i = 1; i < BPF_REG_SIZE; i++) {
-@@ -2619,8 +2658,6 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+@@ -2615,8 +2654,6 @@ static int check_stack_read_fixed_off(st
                }
                mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
        } else {
@@ -205,7 +203,7 @@ index a6c931fed39b..e06b84c7b890 100644
                for (i = 0; i < size; i++) {
                        type = stype[(slot - i) % BPF_REG_SIZE];
                        if (type == STACK_MISC)
-@@ -4106,7 +4143,7 @@ static int check_stack_range_initialized(
+@@ -4102,7 +4139,7 @@ static int check_stack_range_initialized
                        if (clobber) {
                                __mark_reg_unknown(env, &state->stack[spi].spilled_ptr);
                                for (j = 0; j < BPF_REG_SIZE; j++)
@@ -214,6 +212,3 @@ index a6c931fed39b..e06b84c7b890 100644
                        }
                        goto mark;
                }
--- 
-2.39.0
-
diff --git a/queue-5.10/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch b/queue-5.10/f2fs-fix-to-do-sanity-check-on-i_extra_isize-in-is_alive.patch
new file mode 100644 (file)
index 0000000..4f847aa
--- /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
+@@ -977,7 +977,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);
+@@ -1003,11 +1003,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-5.10/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch b/queue-5.10/fbdev-smscufx-fix-error-handling-code-in-ufx_usb_probe.patch
new file mode 100644 (file)
index 0000000..a766a57
--- /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
+@@ -1621,7 +1621,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 */
+@@ -1653,15 +1653,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;
+@@ -1704,22 +1706,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,
+@@ -1727,21 +1741,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)
index 43cce454069e6b86f90071bc87957700b960ef18..d704de422cffd5f6ffef16f8f3c901fcfe2915d1 100644 (file)
@@ -84,3 +84,6 @@ nvmem-core-fix-cell-removal-on-error.patch
 udf-avoid-using-stale-lengthofimpuse.patch
 serial-8250_dma-fix-dma-rx-completion-race.patch
 serial-8250_dma-fix-dma-rx-rearm-race.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
diff --git a/queue-5.10/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch b/queue-5.10/wifi-brcmfmac-check-the-count-value-of-channel-spec-to-prevent-out-of-bounds-reads.patch
new file mode 100644 (file)
index 0000000..0dce28e
--- /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
+@@ -90,6 +90,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)) {
+@@ -6459,6 +6462,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);
+@@ -6604,6 +6614,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);