From: Greg Kroah-Hartman Date: Sun, 30 May 2021 14:20:09 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.4.271~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2123f777c3de45468782609825e91b4fe3a44686;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: bluetooth-cmtp-fix-file-refcount-when-cmtp_attach_device-fails.patch drm-meson-fix-shutdown-crash-when-component-not-probed.patch net-mlx4-fix-eeprom-dump-support.patch nfs-don-t-corrupt-the-value-of-pg_bytes_written-in-nfs_do_recoalesce.patch nfs-fix-an-incorrect-limit-in-filelayout_decode_layout.patch nfsv4-fix-v4.0-v4.1-seek_data-return-enotsupp-when-set-nfs_v4_2-config.patch revert-net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch tipc-skb_linearize-the-head-skb-when-reassembling-msgs.patch tipc-wait-and-exit-until-all-work-queues-are-done.patch --- diff --git a/queue-4.19/bluetooth-cmtp-fix-file-refcount-when-cmtp_attach_device-fails.patch b/queue-4.19/bluetooth-cmtp-fix-file-refcount-when-cmtp_attach_device-fails.patch new file mode 100644 index 00000000000..530250ab3f0 --- /dev/null +++ b/queue-4.19/bluetooth-cmtp-fix-file-refcount-when-cmtp_attach_device-fails.patch @@ -0,0 +1,40 @@ +From 8da3a0b87f4f1c3a3bbc4bfb78cf68476e97d183 Mon Sep 17 00:00:00 2001 +From: Thadeu Lima de Souza Cascardo +Date: Tue, 13 Apr 2021 13:21:03 -0300 +Subject: Bluetooth: cmtp: fix file refcount when cmtp_attach_device fails + +From: Thadeu Lima de Souza Cascardo + +commit 8da3a0b87f4f1c3a3bbc4bfb78cf68476e97d183 upstream. + +When cmtp_attach_device fails, cmtp_add_connection returns the error value +which leads to the caller to doing fput through sockfd_put. But +cmtp_session kthread, which is stopped in this path will also call fput, +leading to a potential refcount underflow or a use-after-free. + +Add a refcount before we signal the kthread to stop. The kthread will try +to grab the cmtp_session_sem mutex before doing the fput, which is held +when get_file is called, so there should be no races there. + +Reported-by: Ryota Shiga +Signed-off-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/cmtp/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/bluetooth/cmtp/core.c ++++ b/net/bluetooth/cmtp/core.c +@@ -391,6 +391,11 @@ int cmtp_add_connection(struct cmtp_conn + if (!(session->flags & BIT(CMTP_LOOPBACK))) { + err = cmtp_attach_device(session); + if (err < 0) { ++ /* Caller will call fput in case of failure, and so ++ * will cmtp_session kthread. ++ */ ++ get_file(session->sock->file); ++ + atomic_inc(&session->terminate); + wake_up_interruptible(sk_sleep(session->sock->sk)); + up_write(&cmtp_session_sem); diff --git a/queue-4.19/drm-meson-fix-shutdown-crash-when-component-not-probed.patch b/queue-4.19/drm-meson-fix-shutdown-crash-when-component-not-probed.patch new file mode 100644 index 00000000000..55446ee7bca --- /dev/null +++ b/queue-4.19/drm-meson-fix-shutdown-crash-when-component-not-probed.patch @@ -0,0 +1,59 @@ +From 7cfc4ea78fc103ea51ecbacd9236abb5b1c490d2 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 30 Apr 2021 10:27:44 +0200 +Subject: drm/meson: fix shutdown crash when component not probed + +From: Neil Armstrong + +commit 7cfc4ea78fc103ea51ecbacd9236abb5b1c490d2 upstream. + +When main component is not probed, by example when the dw-hdmi module is +not loaded yet or in probe defer, the following crash appears on shutdown: + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000038 +... +pc : meson_drv_shutdown+0x24/0x50 +lr : platform_drv_shutdown+0x20/0x30 +... +Call trace: +meson_drv_shutdown+0x24/0x50 +platform_drv_shutdown+0x20/0x30 +device_shutdown+0x158/0x360 +kernel_restart_prepare+0x38/0x48 +kernel_restart+0x18/0x68 +__do_sys_reboot+0x224/0x250 +__arm64_sys_reboot+0x24/0x30 +... + +Simply check if the priv struct has been allocated before using it. + +Fixes: fa0c16caf3d7 ("drm: meson_drv add shutdown function") +Reported-by: Stefan Agner +Signed-off-by: Neil Armstrong +Tested-by: Martin Blumenstingl +Reviewed-by: Martin Blumenstingl +Link: https://patchwork.freedesktop.org/patch/msgid/20210430082744.3638743-1-narmstrong@baylibre.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/meson/meson_drv.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -387,11 +387,12 @@ static int meson_probe_remote(struct pla + static void meson_drv_shutdown(struct platform_device *pdev) + { + struct meson_drm *priv = dev_get_drvdata(&pdev->dev); +- struct drm_device *drm = priv->drm; + +- DRM_DEBUG_DRIVER("\n"); +- drm_kms_helper_poll_fini(drm); +- drm_atomic_helper_shutdown(drm); ++ if (!priv) ++ return; ++ ++ drm_kms_helper_poll_fini(priv->drm); ++ drm_atomic_helper_shutdown(priv->drm); + } + + static int meson_drv_probe(struct platform_device *pdev) diff --git a/queue-4.19/net-mlx4-fix-eeprom-dump-support.patch b/queue-4.19/net-mlx4-fix-eeprom-dump-support.patch new file mode 100644 index 00000000000..90a69988e20 --- /dev/null +++ b/queue-4.19/net-mlx4-fix-eeprom-dump-support.patch @@ -0,0 +1,198 @@ +From db825feefc6868896fed5e361787ba3bee2fd906 Mon Sep 17 00:00:00 2001 +From: Vladyslav Tarasiuk +Date: Sun, 9 May 2021 09:43:18 +0300 +Subject: net/mlx4: Fix EEPROM dump support + +From: Vladyslav Tarasiuk + +commit db825feefc6868896fed5e361787ba3bee2fd906 upstream. + +Fix SFP and QSFP* EEPROM queries by setting i2c_address, offset and page +number correctly. For SFP set the following params: +- I2C address for offsets 0-255 is 0x50. For 256-511 - 0x51. +- Page number is zero. +- Offset is 0-255. + +At the same time, QSFP* parameters are different: +- I2C address is always 0x50. +- Page number is not limited to zero. +- Offset is 0-255 for page zero and 128-255 for others. + +To set parameters accordingly to cable used, implement function to query +module ID and implement respective helper functions to set parameters +correctly. + +Fixes: 135dd9594f12 ("net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query") +Signed-off-by: Vladyslav Tarasiuk +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 4 + drivers/net/ethernet/mellanox/mlx4/port.c | 107 +++++++++++++++++++++++- + 2 files changed, 104 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -2011,8 +2011,6 @@ static int mlx4_en_set_tunable(struct ne + return ret; + } + +-#define MLX4_EEPROM_PAGE_LEN 256 +- + static int mlx4_en_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) + { +@@ -2047,7 +2045,7 @@ static int mlx4_en_get_module_info(struc + break; + case MLX4_MODULE_ID_SFP: + modinfo->type = ETH_MODULE_SFF_8472; +- modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; ++ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + break; + default: + return -EINVAL; +--- a/drivers/net/ethernet/mellanox/mlx4/port.c ++++ b/drivers/net/ethernet/mellanox/mlx4/port.c +@@ -1973,6 +1973,7 @@ EXPORT_SYMBOL(mlx4_get_roce_gid_from_sla + #define I2C_ADDR_LOW 0x50 + #define I2C_ADDR_HIGH 0x51 + #define I2C_PAGE_SIZE 256 ++#define I2C_HIGH_PAGE_SIZE 128 + + /* Module Info Data */ + struct mlx4_cable_info { +@@ -2026,6 +2027,88 @@ static inline const char *cable_info_mad + return "Unknown Error"; + } + ++static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) ++{ ++ struct mlx4_cmd_mailbox *inbox, *outbox; ++ struct mlx4_mad_ifc *inmad, *outmad; ++ struct mlx4_cable_info *cable_info; ++ int ret; ++ ++ inbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(inbox)) ++ return PTR_ERR(inbox); ++ ++ outbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(outbox)) { ++ mlx4_free_cmd_mailbox(dev, inbox); ++ return PTR_ERR(outbox); ++ } ++ ++ inmad = (struct mlx4_mad_ifc *)(inbox->buf); ++ outmad = (struct mlx4_mad_ifc *)(outbox->buf); ++ ++ inmad->method = 0x1; /* Get */ ++ inmad->class_version = 0x1; ++ inmad->mgmt_class = 0x1; ++ inmad->base_version = 0x1; ++ inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ ++ ++ cable_info = (struct mlx4_cable_info *)inmad->data; ++ cable_info->dev_mem_address = 0; ++ cable_info->page_num = 0; ++ cable_info->i2c_addr = I2C_ADDR_LOW; ++ cable_info->size = cpu_to_be16(1); ++ ++ ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, ++ MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, ++ MLX4_CMD_NATIVE); ++ if (ret) ++ goto out; ++ ++ if (be16_to_cpu(outmad->status)) { ++ /* Mad returned with bad status */ ++ ret = be16_to_cpu(outmad->status); ++ mlx4_warn(dev, ++ "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", ++ 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, ++ cable_info_mad_err_str(ret)); ++ ret = -ret; ++ goto out; ++ } ++ cable_info = (struct mlx4_cable_info *)outmad->data; ++ *module_id = cable_info->data[0]; ++out: ++ mlx4_free_cmd_mailbox(dev, inbox); ++ mlx4_free_cmd_mailbox(dev, outbox); ++ return ret; ++} ++ ++static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ *i2c_addr = I2C_ADDR_LOW; ++ *page_num = 0; ++ ++ if (*offset < I2C_PAGE_SIZE) ++ return; ++ ++ *i2c_addr = I2C_ADDR_HIGH; ++ *offset -= I2C_PAGE_SIZE; ++} ++ ++static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ /* Offsets 0-255 belong to page 0. ++ * Offsets 256-639 belong to pages 01, 02, 03. ++ * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 ++ */ ++ if (*offset < I2C_PAGE_SIZE) ++ *page_num = 0; ++ else ++ *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; ++ *i2c_addr = I2C_ADDR_LOW; ++ *offset -= *page_num * I2C_HIGH_PAGE_SIZE; ++} ++ + /** + * mlx4_get_module_info - Read cable module eeprom data + * @dev: mlx4_dev. +@@ -2045,12 +2128,30 @@ int mlx4_get_module_info(struct mlx4_dev + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; +- u16 i2c_addr; ++ u8 module_id, i2c_addr, page_num; + int ret; + + if (size > MODULE_INFO_MAX_READ) + size = MODULE_INFO_MAX_READ; + ++ ret = mlx4_get_module_id(dev, port, &module_id); ++ if (ret) ++ return ret; ++ ++ switch (module_id) { ++ case MLX4_MODULE_ID_SFP: ++ mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ case MLX4_MODULE_ID_QSFP: ++ case MLX4_MODULE_ID_QSFP_PLUS: ++ case MLX4_MODULE_ID_QSFP28: ++ mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ default: ++ mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); ++ return -EINVAL; ++ } ++ + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); +@@ -2076,11 +2177,9 @@ int mlx4_get_module_info(struct mlx4_dev + */ + size -= offset + size - I2C_PAGE_SIZE; + +- i2c_addr = I2C_ADDR_LOW; +- + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = cpu_to_be16(offset); +- cable_info->page_num = 0; ++ cable_info->page_num = page_num; + cable_info->i2c_addr = i2c_addr; + cable_info->size = cpu_to_be16(size); + diff --git a/queue-4.19/nfs-don-t-corrupt-the-value-of-pg_bytes_written-in-nfs_do_recoalesce.patch b/queue-4.19/nfs-don-t-corrupt-the-value-of-pg_bytes_written-in-nfs_do_recoalesce.patch new file mode 100644 index 00000000000..d74ddfa60df --- /dev/null +++ b/queue-4.19/nfs-don-t-corrupt-the-value-of-pg_bytes_written-in-nfs_do_recoalesce.patch @@ -0,0 +1,52 @@ +From 0d0ea309357dea0d85a82815f02157eb7fcda39f Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 25 May 2021 10:40:12 -0400 +Subject: NFS: Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() + +From: Trond Myklebust + +commit 0d0ea309357dea0d85a82815f02157eb7fcda39f upstream. + +The value of mirror->pg_bytes_written should only be updated after a +successful attempt to flush out the requests on the list. + +Fixes: a7d42ddb3099 ("nfs: add mirroring support to pgio layer") +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/pagelist.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/fs/nfs/pagelist.c ++++ b/fs/nfs/pagelist.c +@@ -987,17 +987,16 @@ static void nfs_pageio_doio(struct nfs_p + { + struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); + +- + if (!list_empty(&mirror->pg_list)) { + int error = desc->pg_ops->pg_doio(desc); + if (error < 0) + desc->pg_error = error; +- else ++ if (list_empty(&mirror->pg_list)) { + mirror->pg_bytes_written += mirror->pg_count; +- } +- if (list_empty(&mirror->pg_list)) { +- mirror->pg_count = 0; +- mirror->pg_base = 0; ++ mirror->pg_count = 0; ++ mirror->pg_base = 0; ++ mirror->pg_recoalesce = 0; ++ } + } + } + +@@ -1095,7 +1094,6 @@ static int nfs_do_recoalesce(struct nfs_ + + do { + list_splice_init(&mirror->pg_list, &head); +- mirror->pg_bytes_written -= mirror->pg_count; + mirror->pg_count = 0; + mirror->pg_base = 0; + mirror->pg_recoalesce = 0; diff --git a/queue-4.19/nfs-fix-an-incorrect-limit-in-filelayout_decode_layout.patch b/queue-4.19/nfs-fix-an-incorrect-limit-in-filelayout_decode_layout.patch new file mode 100644 index 00000000000..55cf5157a0a --- /dev/null +++ b/queue-4.19/nfs-fix-an-incorrect-limit-in-filelayout_decode_layout.patch @@ -0,0 +1,34 @@ +From 769b01ea68b6c49dc3cde6adf7e53927dacbd3a8 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 11 May 2021 11:49:42 +0300 +Subject: NFS: fix an incorrect limit in filelayout_decode_layout() + +From: Dan Carpenter + +commit 769b01ea68b6c49dc3cde6adf7e53927dacbd3a8 upstream. + +The "sizeof(struct nfs_fh)" is two bytes too large and could lead to +memory corruption. It should be NFS_MAXFHSIZE because that's the size +of the ->data[] buffer. + +I reversed the size of the arguments to put the variable on the left. + +Fixes: 16b374ca439f ("NFSv4.1: pnfs: filelayout: add driver's LAYOUTGET and GETDEVICEINFO infrastructure") +Signed-off-by: Dan Carpenter +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/filelayout/filelayout.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/filelayout/filelayout.c ++++ b/fs/nfs/filelayout/filelayout.c +@@ -717,7 +717,7 @@ filelayout_decode_layout(struct pnfs_lay + if (unlikely(!p)) + goto out_err; + fl->fh_array[i]->size = be32_to_cpup(p++); +- if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { ++ if (fl->fh_array[i]->size > NFS_MAXFHSIZE) { + printk(KERN_ERR "NFS: Too big fh %d received %d\n", + i, fl->fh_array[i]->size); + goto out_err; diff --git a/queue-4.19/nfsv4-fix-v4.0-v4.1-seek_data-return-enotsupp-when-set-nfs_v4_2-config.patch b/queue-4.19/nfsv4-fix-v4.0-v4.1-seek_data-return-enotsupp-when-set-nfs_v4_2-config.patch new file mode 100644 index 00000000000..2e6044e6ed5 --- /dev/null +++ b/queue-4.19/nfsv4-fix-v4.0-v4.1-seek_data-return-enotsupp-when-set-nfs_v4_2-config.patch @@ -0,0 +1,36 @@ +From e67afa7ee4a59584d7253e45d7f63b9528819a13 Mon Sep 17 00:00:00 2001 +From: Zhang Xiaoxu +Date: Tue, 25 May 2021 23:32:35 -0400 +Subject: NFSv4: Fix v4.0/v4.1 SEEK_DATA return -ENOTSUPP when set NFS_V4_2 config + +From: Zhang Xiaoxu + +commit e67afa7ee4a59584d7253e45d7f63b9528819a13 upstream. + +Since commit bdcc2cd14e4e ("NFSv4.2: handle NFS-specific llseek errors"), +nfs42_proc_llseek would return -EOPNOTSUPP rather than -ENOTSUPP when +SEEK_DATA on NFSv4.0/v4.1. + +This will lead xfstests generic/285 not run on NFSv4.0/v4.1 when set the +CONFIG_NFS_V4_2, rather than run failed. + +Fixes: bdcc2cd14e4e ("NFSv4.2: handle NFS-specific llseek errors") +Cc: # 4.2 +Signed-off-by: Zhang Xiaoxu +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/nfs4file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -148,7 +148,7 @@ static loff_t nfs4_file_llseek(struct fi + case SEEK_HOLE: + case SEEK_DATA: + ret = nfs42_proc_llseek(filep, offset, whence); +- if (ret != -ENOTSUPP) ++ if (ret != -EOPNOTSUPP) + return ret; + /* Fall through */ + default: diff --git a/queue-4.19/revert-net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch b/queue-4.19/revert-net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch new file mode 100644 index 00000000000..9e4556b20ed --- /dev/null +++ b/queue-4.19/revert-net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch @@ -0,0 +1,36 @@ +From 75016891357a628d2b8acc09e2b9b2576c18d318 Mon Sep 17 00:00:00 2001 +From: Hoang Le +Date: Fri, 14 May 2021 08:23:03 +0700 +Subject: Revert "net:tipc: Fix a double free in tipc_sk_mcast_rcv" + +From: Hoang Le + +commit 75016891357a628d2b8acc09e2b9b2576c18d318 upstream. + +This reverts commit 6bf24dc0cc0cc43b29ba344b66d78590e687e046. +Above fix is not correct and caused memory leak issue. + +Fixes: 6bf24dc0cc0c ("net:tipc: Fix a double free in tipc_sk_mcast_rcv") +Acked-by: Jon Maloy +Acked-by: Tung Nguyen +Signed-off-by: Hoang Le +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/socket.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -1187,7 +1187,10 @@ void tipc_sk_mcast_rcv(struct net *net, + spin_lock_bh(&inputq->lock); + if (skb_peek(arrvq) == skb) { + skb_queue_splice_tail_init(&tmpq, inputq); +- __skb_dequeue(arrvq); ++ /* Decrease the skb's refcnt as increasing in the ++ * function tipc_skb_peek ++ */ ++ kfree_skb(__skb_dequeue(arrvq)); + } + spin_unlock_bh(&inputq->lock); + __skb_queue_purge(&tmpq); diff --git a/queue-4.19/series b/queue-4.19/series index f5f5b510fe7..8eb96a525bd 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -59,3 +59,12 @@ bpf-no-need-to-simulate-speculative-domain-for-immediates.patch spi-gpio-don-t-leak-spi-master-in-probe-error-path.patch spi-mt7621-disable-clock-in-probe-error-path.patch spi-mt7621-don-t-leak-spi-master-in-probe-error-path.patch +bluetooth-cmtp-fix-file-refcount-when-cmtp_attach_device-fails.patch +nfs-fix-an-incorrect-limit-in-filelayout_decode_layout.patch +nfs-don-t-corrupt-the-value-of-pg_bytes_written-in-nfs_do_recoalesce.patch +nfsv4-fix-v4.0-v4.1-seek_data-return-enotsupp-when-set-nfs_v4_2-config.patch +drm-meson-fix-shutdown-crash-when-component-not-probed.patch +net-mlx4-fix-eeprom-dump-support.patch +revert-net-tipc-fix-a-double-free-in-tipc_sk_mcast_rcv.patch +tipc-wait-and-exit-until-all-work-queues-are-done.patch +tipc-skb_linearize-the-head-skb-when-reassembling-msgs.patch diff --git a/queue-4.19/tipc-skb_linearize-the-head-skb-when-reassembling-msgs.patch b/queue-4.19/tipc-skb_linearize-the-head-skb-when-reassembling-msgs.patch new file mode 100644 index 00000000000..d7cb9af9246 --- /dev/null +++ b/queue-4.19/tipc-skb_linearize-the-head-skb-when-reassembling-msgs.patch @@ -0,0 +1,95 @@ +From b7df21cf1b79ab7026f545e7bf837bd5750ac026 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Sat, 8 May 2021 03:57:03 +0800 +Subject: tipc: skb_linearize the head skb when reassembling msgs + +From: Xin Long + +commit b7df21cf1b79ab7026f545e7bf837bd5750ac026 upstream. + +It's not a good idea to append the frag skb to a skb's frag_list if +the frag_list already has skbs from elsewhere, such as this skb was +created by pskb_copy() where the frag_list was cloned (all the skbs +in it were skb_get'ed) and shared by multiple skbs. + +However, the new appended frag skb should have been only seen by the +current skb. Otherwise, it will cause use after free crashes as this +appended frag skb are seen by multiple skbs but it only got skb_get +called once. + +The same thing happens with a skb updated by pskb_may_pull() with a +skb_cloned skb. Li Shuang has reported quite a few crashes caused +by this when doing testing over macvlan devices: + + [] kernel BUG at net/core/skbuff.c:1970! + [] Call Trace: + [] skb_clone+0x4d/0xb0 + [] macvlan_broadcast+0xd8/0x160 [macvlan] + [] macvlan_process_broadcast+0x148/0x150 [macvlan] + [] process_one_work+0x1a7/0x360 + [] worker_thread+0x30/0x390 + + [] kernel BUG at mm/usercopy.c:102! + [] Call Trace: + [] __check_heap_object+0xd3/0x100 + [] __check_object_size+0xff/0x16b + [] simple_copy_to_iter+0x1c/0x30 + [] __skb_datagram_iter+0x7d/0x310 + [] __skb_datagram_iter+0x2a5/0x310 + [] skb_copy_datagram_iter+0x3b/0x90 + [] tipc_recvmsg+0x14a/0x3a0 [tipc] + [] ____sys_recvmsg+0x91/0x150 + [] ___sys_recvmsg+0x7b/0xc0 + + [] kernel BUG at mm/slub.c:305! + [] Call Trace: + [] + [] kmem_cache_free+0x3ff/0x400 + [] __netif_receive_skb_core+0x12c/0xc40 + [] ? kmem_cache_alloc+0x12e/0x270 + [] netif_receive_skb_internal+0x3d/0xb0 + [] ? get_rx_page_info+0x8e/0xa0 [be2net] + [] be_poll+0x6ef/0xd00 [be2net] + [] ? irq_exit+0x4f/0x100 + [] net_rx_action+0x149/0x3b0 + + ... + +This patch is to fix it by linearizing the head skb if it has frag_list +set in tipc_buf_append(). Note that we choose to do this before calling +skb_unshare(), as __skb_linearize() will avoid skb_copy(). Also, we can +not just drop the frag_list either as the early time. + +Fixes: 45c8b7b175ce ("tipc: allow non-linear first fragment buffer") +Reported-by: Li Shuang +Signed-off-by: Xin Long +Acked-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/msg.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -141,18 +141,13 @@ int tipc_buf_append(struct sk_buff **hea + if (unlikely(head)) + goto err; + *buf = NULL; ++ if (skb_has_frag_list(frag) && __skb_linearize(frag)) ++ goto err; + frag = skb_unshare(frag, GFP_ATOMIC); + if (unlikely(!frag)) + goto err; + head = *headbuf = frag; + TIPC_SKB_CB(head)->tail = NULL; +- if (skb_is_nonlinear(head)) { +- skb_walk_frags(head, tail) { +- TIPC_SKB_CB(head)->tail = tail; +- } +- } else { +- skb_frag_list_init(head); +- } + return 0; + } + diff --git a/queue-4.19/tipc-wait-and-exit-until-all-work-queues-are-done.patch b/queue-4.19/tipc-wait-and-exit-until-all-work-queues-are-done.patch new file mode 100644 index 00000000000..1f5d1be856b --- /dev/null +++ b/queue-4.19/tipc-wait-and-exit-until-all-work-queues-are-done.patch @@ -0,0 +1,82 @@ +From 04c26faa51d1e2fe71cf13c45791f5174c37f986 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Mon, 17 May 2021 02:28:58 +0800 +Subject: tipc: wait and exit until all work queues are done + +From: Xin Long + +commit 04c26faa51d1e2fe71cf13c45791f5174c37f986 upstream. + +On some host, a crash could be triggered simply by repeating these +commands several times: + + # modprobe tipc + # tipc bearer enable media udp name UDP1 localip 127.0.0.1 + # rmmod tipc + + [] BUG: unable to handle kernel paging request at ffffffffc096bb00 + [] Workqueue: events 0xffffffffc096bb00 + [] Call Trace: + [] ? process_one_work+0x1a7/0x360 + [] ? worker_thread+0x30/0x390 + [] ? create_worker+0x1a0/0x1a0 + [] ? kthread+0x116/0x130 + [] ? kthread_flush_work_fn+0x10/0x10 + [] ? ret_from_fork+0x35/0x40 + +When removing the TIPC module, the UDP tunnel sock will be delayed to +release in a work queue as sock_release() can't be done in rtnl_lock(). +If the work queue is schedule to run after the TIPC module is removed, +kernel will crash as the work queue function cleanup_beareri() code no +longer exists when trying to invoke it. + +To fix it, this patch introduce a member wq_count in tipc_net to track +the numbers of work queues in schedule, and wait and exit until all +work queues are done in tipc_exit_net(). + +Fixes: d0f91938bede ("tipc: add ip/udp media type") +Reported-by: Shuang Li +Signed-off-by: Xin Long +Acked-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/core.c | 3 +++ + net/tipc/core.h | 3 +++ + net/tipc/udp_media.c | 1 + + 3 files changed, 7 insertions(+) + +--- a/net/tipc/core.c ++++ b/net/tipc/core.c +@@ -101,6 +101,9 @@ static void __net_exit tipc_exit_net(str + tipc_bcast_stop(net); + tipc_nametbl_stop(net); + tipc_sk_rht_destroy(net); ++ ++ while (atomic_read(&tn->wq_count)) ++ cond_resched(); + } + + static struct pernet_operations tipc_net_ops = { +--- a/net/tipc/core.h ++++ b/net/tipc/core.h +@@ -122,6 +122,9 @@ struct tipc_net { + /* Topology subscription server */ + struct tipc_topsrv *topsrv; + atomic_t subscription_count; ++ ++ /* The numbers of work queues in schedule */ ++ atomic_t wq_count; + }; + + static inline struct tipc_net *tipc_net(struct net *net) +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -792,6 +792,7 @@ static void tipc_udp_disable(struct tipc + RCU_INIT_POINTER(ub->bearer, NULL); + + /* sock_release need to be done outside of rtnl lock */ ++ atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); + INIT_WORK(&ub->work, cleanup_bearer); + schedule_work(&ub->work); + }