From: Greg Kroah-Hartman Date: Mon, 1 Apr 2019 12:05:05 +0000 (+0200) Subject: 5.0-stable patches X-Git-Tag: v3.18.138~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53bc0d3540aecea3d11bbd5cf5ad601d56b12d5a;p=thirdparty%2Fkernel%2Fstable-queue.git 5.0-stable patches added patches: bpf-do-not-restore-dst_reg-when-cur_state-is-freed.patch mt76x02u-use-usb_bulk_msg-to-upload-firmware.patch --- diff --git a/queue-5.0/bpf-do-not-restore-dst_reg-when-cur_state-is-freed.patch b/queue-5.0/bpf-do-not-restore-dst_reg-when-cur_state-is-freed.patch new file mode 100644 index 00000000000..c4f79bd62c9 --- /dev/null +++ b/queue-5.0/bpf-do-not-restore-dst_reg-when-cur_state-is-freed.patch @@ -0,0 +1,71 @@ +From 0803278b0b4d8eeb2b461fb698785df65a725d9e Mon Sep 17 00:00:00 2001 +From: Xu Yu +Date: Thu, 21 Mar 2019 18:00:35 +0800 +Subject: bpf: do not restore dst_reg when cur_state is freed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xu Yu + +commit 0803278b0b4d8eeb2b461fb698785df65a725d9e upstream. + +Syzkaller hit 'KASAN: use-after-free Write in sanitize_ptr_alu' bug. + +Call trace: + + dump_stack+0xbf/0x12e + print_address_description+0x6a/0x280 + kasan_report+0x237/0x360 + sanitize_ptr_alu+0x85a/0x8d0 + adjust_ptr_min_max_vals+0x8f2/0x1ca0 + adjust_reg_min_max_vals+0x8ed/0x22e0 + do_check+0x1ca6/0x5d00 + bpf_check+0x9ca/0x2570 + bpf_prog_load+0xc91/0x1030 + __se_sys_bpf+0x61e/0x1f00 + do_syscall_64+0xc8/0x550 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Fault injection trace: + +  kfree+0xea/0x290 +  free_func_state+0x4a/0x60 +  free_verifier_state+0x61/0xe0 +  push_stack+0x216/0x2f0 <- inject failslab +  sanitize_ptr_alu+0x2b1/0x8d0 +  adjust_ptr_min_max_vals+0x8f2/0x1ca0 +  adjust_reg_min_max_vals+0x8ed/0x22e0 +  do_check+0x1ca6/0x5d00 +  bpf_check+0x9ca/0x2570 +  bpf_prog_load+0xc91/0x1030 +  __se_sys_bpf+0x61e/0x1f00 +  do_syscall_64+0xc8/0x550 +  entry_SYSCALL_64_after_hwframe+0x49/0xbe + +When kzalloc() fails in push_stack(), free_verifier_state() will free +current verifier state. As push_stack() returns, dst_reg was restored +if ptr_is_dst_reg is false. However, as member of the cur_state, +dst_reg is also freed, and error occurs when dereferencing dst_reg. +Simply fix it by testing ret of push_stack() before restoring dst_reg. + +Fixes: 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") +Signed-off-by: Xu Yu +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/bpf/verifier.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3187,7 +3187,7 @@ do_sim: + *dst_reg = *ptr_reg; + } + ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true); +- if (!ptr_is_dst_reg) ++ if (!ptr_is_dst_reg && ret) + *dst_reg = tmp; + return !ret ? -EFAULT : 0; + } diff --git a/queue-5.0/mt76x02u-use-usb_bulk_msg-to-upload-firmware.patch b/queue-5.0/mt76x02u-use-usb_bulk_msg-to-upload-firmware.patch new file mode 100644 index 00000000000..42cf4a3c714 --- /dev/null +++ b/queue-5.0/mt76x02u-use-usb_bulk_msg-to-upload-firmware.patch @@ -0,0 +1,174 @@ +From 5de4db8fcb6d6fc7d9064c22841211790c0ab81b Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Mon, 11 Feb 2019 09:16:14 +0100 +Subject: mt76x02u: use usb_bulk_msg to upload firmware + +From: Stanislaw Gruszka + +commit 5de4db8fcb6d6fc7d9064c22841211790c0ab81b upstream. + +We don't need to send firmware data asynchronously, much simpler is just +use synchronous usb_bulk_msg(). + +[ stable note: this patch was originally developed as cleanup, but it +remove incorrect usage of page_frag_alloc(): alloc more than PAGE_SIZE +and create not ARCH_DMA_MINALIGN dma buffers needed at least for +performance reason. Was tested on 5.0 and 4.20, see +https://bugzilla.kernel.org/show_bug.cgi?id=202673 and +https://bugzilla.kernel.org/show_bug.cgi?id=202241 ] + +Tested-by: Lorenzo Bianconi +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Felix Fietkau +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 13 ++++ + drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 52 +++++-------------- + drivers/net/wireless/mediatek/mt76/usb.c | 1 + 3 files changed, 29 insertions(+), 37 deletions(-) + +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -713,6 +713,19 @@ static inline bool mt76u_check_sg(struct + udev->speed == USB_SPEED_WIRELESS)); + } + ++static inline int ++mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int timeout) ++{ ++ struct usb_interface *intf = to_usb_interface(dev->dev); ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct mt76_usb *usb = &dev->usb; ++ unsigned int pipe; ++ int sent; ++ ++ pipe = usb_sndbulkpipe(udev, usb->out_ep[MT_EP_OUT_INBAND_CMD]); ++ return usb_bulk_msg(udev, pipe, data, len, &sent, timeout); ++} ++ + int mt76u_vendor_request(struct mt76_dev *dev, u8 req, + u8 req_type, u16 val, u16 offset, + void *buf, size_t len); +--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +@@ -121,18 +121,14 @@ static int + __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) + { +- struct usb_interface *intf = to_usb_interface(dev->dev); +- struct usb_device *udev = interface_to_usbdev(intf); + struct mt76_usb *usb = &dev->usb; +- unsigned int pipe; +- int ret, sent; ++ int ret; + u8 seq = 0; + u32 info; + + if (test_bit(MT76_REMOVED, &dev->state)) + return 0; + +- pipe = usb_sndbulkpipe(udev, usb->out_ep[MT_EP_OUT_INBAND_CMD]); + if (wait_resp) { + seq = ++usb->mcu.msg_seq & 0xf; + if (!seq) +@@ -146,7 +142,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev + if (ret) + return ret; + +- ret = usb_bulk_msg(udev, pipe, skb->data, skb->len, &sent, 500); ++ ret = mt76u_bulk_msg(dev, skb->data, skb->len, 500); + if (ret) + return ret; + +@@ -268,14 +264,12 @@ void mt76x02u_mcu_fw_reset(struct mt76x0 + EXPORT_SYMBOL_GPL(mt76x02u_mcu_fw_reset); + + static int +-__mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, struct mt76u_buf *buf, ++__mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, u8 *data, + const void *fw_data, int len, u32 dst_addr) + { +- u8 *data = sg_virt(&buf->urb->sg[0]); +- DECLARE_COMPLETION_ONSTACK(cmpl); + __le32 info; + u32 val; +- int err; ++ int err, data_len; + + info = cpu_to_le32(FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | + FIELD_PREP(MT_MCU_MSG_LEN, len) | +@@ -291,25 +285,12 @@ __mt76x02u_mcu_fw_send_data(struct mt76x + mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, + MT_FCE_DMA_LEN, len << 16); + +- buf->len = MT_CMD_HDR_LEN + len + sizeof(info); +- err = mt76u_submit_buf(&dev->mt76, USB_DIR_OUT, +- MT_EP_OUT_INBAND_CMD, +- buf, GFP_KERNEL, +- mt76u_mcu_complete_urb, &cmpl); +- if (err < 0) +- return err; +- +- if (!wait_for_completion_timeout(&cmpl, +- msecs_to_jiffies(1000))) { +- dev_err(dev->mt76.dev, "firmware upload timed out\n"); +- usb_kill_urb(buf->urb); +- return -ETIMEDOUT; +- } ++ data_len = MT_CMD_HDR_LEN + len + sizeof(info); + +- if (mt76u_urb_error(buf->urb)) { +- dev_err(dev->mt76.dev, "firmware upload failed: %d\n", +- buf->urb->status); +- return buf->urb->status; ++ err = mt76u_bulk_msg(&dev->mt76, data, data_len, 1000); ++ if (err) { ++ dev_err(dev->mt76.dev, "firmware upload failed: %d\n", err); ++ return err; + } + + val = mt76_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); +@@ -322,17 +303,16 @@ __mt76x02u_mcu_fw_send_data(struct mt76x + int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data, + int data_len, u32 max_payload, u32 offset) + { +- int err, len, pos = 0, max_len = max_payload - 8; +- struct mt76u_buf buf; ++ int len, err = 0, pos = 0, max_len = max_payload - 8; ++ u8 *buf; + +- err = mt76u_buf_alloc(&dev->mt76, &buf, 1, max_payload, max_payload, +- GFP_KERNEL); +- if (err < 0) +- return err; ++ buf = kmalloc(max_payload, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; + + while (data_len > 0) { + len = min_t(int, data_len, max_len); +- err = __mt76x02u_mcu_fw_send_data(dev, &buf, data + pos, ++ err = __mt76x02u_mcu_fw_send_data(dev, buf, data + pos, + len, offset + pos); + if (err < 0) + break; +@@ -341,7 +321,7 @@ int mt76x02u_mcu_fw_send_data(struct mt7 + pos += len; + usleep_range(5000, 10000); + } +- mt76u_buf_free(&buf); ++ kfree(buf); + + return err; + } +--- a/drivers/net/wireless/mediatek/mt76/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/usb.c +@@ -326,7 +326,6 @@ int mt76u_buf_alloc(struct mt76_dev *dev + + return mt76u_fill_rx_sg(dev, buf, nsgs, len, sglen); + } +-EXPORT_SYMBOL_GPL(mt76u_buf_alloc); + + void mt76u_buf_free(struct mt76u_buf *buf) + { diff --git a/queue-5.0/series b/queue-5.0/series index e923a526376..a1fc9740542 100644 --- a/queue-5.0/series +++ b/queue-5.0/series @@ -142,3 +142,5 @@ x86-smp-enforce-config_hotplug_cpu-when-smp-y.patch kvm-reject-device-ioctls-from-processes-other-than-the-vm-s-creator.patch kvm-x86-emulate-msr_ia32_arch_capabilities-on-amd-hosts.patch kvm-x86-update-rip-after-emulating-io.patch +bpf-do-not-restore-dst_reg-when-cur_state-is-freed.patch +mt76x02u-use-usb_bulk_msg-to-upload-firmware.patch