From 175dacaf8cb2c6e64e99676d4927094fa553b4e3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Sep 2018 09:59:05 +0200 Subject: [PATCH] 4.9-stable patches added patches: be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch net-mlx5-fix-use-after-free-in-self-healing-flow.patch rds-fix-two-rcu-related-problems.patch --- ...ry-leak-in-be_cmd_get_profile_config.patch | 31 +++++++ ...eanup-in-the-device-init-remove-flow.patch | 55 +++++++++++++ ...-use-after-free-in-self-healing-flow.patch | 82 +++++++++++++++++++ .../rds-fix-two-rcu-related-problems.patch | 62 ++++++++++++++ queue-4.9/series | 4 + 5 files changed, 234 insertions(+) create mode 100644 queue-4.9/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch create mode 100644 queue-4.9/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch create mode 100644 queue-4.9/net-mlx5-fix-use-after-free-in-self-healing-flow.patch create mode 100644 queue-4.9/rds-fix-two-rcu-related-problems.patch create mode 100644 queue-4.9/series diff --git a/queue-4.9/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch b/queue-4.9/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch new file mode 100644 index 00000000000..e9ba100babb --- /dev/null +++ b/queue-4.9/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch @@ -0,0 +1,31 @@ +From foo@baz Thu Sep 20 09:30:23 CEST 2018 +From: Petr Oros +Date: Wed, 5 Sep 2018 14:37:45 +0200 +Subject: be2net: Fix memory leak in be_cmd_get_profile_config() + +From: Petr Oros + +[ Upstream commit 9d7f19dc4673fbafebfcbf30eb90e09fa7d1c037 ] + +DMA allocated memory is lost in be_cmd_get_profile_config() when we +call it with non-NULL port_res parameter. + +Signed-off-by: Petr Oros +Reviewed-by: Ivan Vecera +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -4500,7 +4500,7 @@ int be_cmd_get_profile_config(struct be_ + port_res->max_vfs += le16_to_cpu(pcie->num_vfs); + } + } +- return status; ++ goto err; + } + + pcie = be_get_pcie_desc(resp->func_param, desc_count, diff --git a/queue-4.9/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch b/queue-4.9/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch new file mode 100644 index 00000000000..07802999271 --- /dev/null +++ b/queue-4.9/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch @@ -0,0 +1,55 @@ +From foo@baz Thu Sep 20 09:30:23 CEST 2018 +From: Jack Morgenstein +Date: Tue, 7 Aug 2018 09:59:03 +0300 +Subject: net/mlx5: Fix debugfs cleanup in the device init/remove flow + +From: Jack Morgenstein + +[ Upstream commit 5df816e7f43f1297c40021ef17ec6e722b45c82f ] + +When initializing the device (procedure init_one), the driver +calls mlx5_pci_init to perform pci initialization. As part of this +initialization, mlx5_pci_init creates a debugfs directory. +If this creation fails, init_one aborts, returning failure to +the caller (which is the probe method caller). + +The main reason for such a failure to occur is if the debugfs +directory already exists. This can happen if the last time +mlx5_pci_close was called, debugfs_remove (silently) failed due +to the debugfs directory not being empty. + +Guarantee that such a debugfs_remove failure will not occur by +instead calling debugfs_remove_recursive in procedure mlx5_pci_close. + +Fixes: 59211bd3b632 ("net/mlx5: Split the load/unload flow into hardware and software flows") +Signed-off-by: Jack Morgenstein +Reviewed-by: Daniel Jurgens +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -787,8 +787,10 @@ static int mlx5_pci_init(struct mlx5_cor + priv->numa_node = dev_to_node(&dev->pdev->dev); + + priv->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), mlx5_debugfs_root); +- if (!priv->dbg_root) ++ if (!priv->dbg_root) { ++ dev_err(&pdev->dev, "Cannot create debugfs dir, aborting\n"); + return -ENOMEM; ++ } + + err = mlx5_pci_enable_device(dev); + if (err) { +@@ -837,7 +839,7 @@ static void mlx5_pci_close(struct mlx5_c + pci_clear_master(dev->pdev); + release_bar(dev->pdev); + mlx5_pci_disable_device(dev); +- debugfs_remove(priv->dbg_root); ++ debugfs_remove_recursive(priv->dbg_root); + } + + static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv) diff --git a/queue-4.9/net-mlx5-fix-use-after-free-in-self-healing-flow.patch b/queue-4.9/net-mlx5-fix-use-after-free-in-self-healing-flow.patch new file mode 100644 index 00000000000..bfcd60d0798 --- /dev/null +++ b/queue-4.9/net-mlx5-fix-use-after-free-in-self-healing-flow.patch @@ -0,0 +1,82 @@ +From foo@baz Thu Sep 20 09:30:23 CEST 2018 +From: Jack Morgenstein +Date: Sun, 5 Aug 2018 09:19:33 +0300 +Subject: net/mlx5: Fix use-after-free in self-healing flow + +From: Jack Morgenstein + +[ Upstream commit 76d5581c870454be5f1f1a106c57985902e7ea20 ] + +When the mlx5 health mechanism detects a problem while the driver +is in the middle of init_one or remove_one, the driver needs to prevent +the health mechanism from scheduling future work; if future work +is scheduled, there is a problem with use-after-free: the system WQ +tries to run the work item (which has been freed) at the scheduled +future time. + +Prevent this by disabling work item scheduling in the health mechanism +when the driver is in the middle of init_one() or remove_one(). + +Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") +Signed-off-by: Jack Morgenstein +Reviewed-by: Feras Daoud +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/health.c | 10 +++++++++- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ++-- + include/linux/mlx5/driver.h | 2 +- + 3 files changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -339,9 +339,17 @@ void mlx5_start_health_poll(struct mlx5_ + add_timer(&health->timer); + } + +-void mlx5_stop_health_poll(struct mlx5_core_dev *dev) ++void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health) + { + struct mlx5_core_health *health = &dev->priv.health; ++ unsigned long flags; ++ ++ if (disable_health) { ++ spin_lock_irqsave(&health->wq_lock, flags); ++ set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags); ++ set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags); ++ spin_unlock_irqrestore(&health->wq_lock, flags); ++ } + + del_timer_sync(&health->timer); + } +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -1130,7 +1130,7 @@ err_cleanup_once: + mlx5_cleanup_once(dev); + + err_stop_poll: +- mlx5_stop_health_poll(dev); ++ mlx5_stop_health_poll(dev, boot); + if (mlx5_cmd_teardown_hca(dev)) { + dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n"); + goto out_err; +@@ -1187,7 +1187,7 @@ static int mlx5_unload_one(struct mlx5_c + mlx5_disable_msix(dev); + if (cleanup) + mlx5_cleanup_once(dev); +- mlx5_stop_health_poll(dev); ++ mlx5_stop_health_poll(dev, cleanup); + err = mlx5_cmd_teardown_hca(dev); + if (err) { + dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n"); +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -786,7 +786,7 @@ void mlx5_unmap_free_uar(struct mlx5_cor + void mlx5_health_cleanup(struct mlx5_core_dev *dev); + int mlx5_health_init(struct mlx5_core_dev *dev); + void mlx5_start_health_poll(struct mlx5_core_dev *dev); +-void mlx5_stop_health_poll(struct mlx5_core_dev *dev); ++void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health); + void mlx5_drain_health_wq(struct mlx5_core_dev *dev); + void mlx5_drain_health_recovery(struct mlx5_core_dev *dev); + int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, diff --git a/queue-4.9/rds-fix-two-rcu-related-problems.patch b/queue-4.9/rds-fix-two-rcu-related-problems.patch new file mode 100644 index 00000000000..7577f80d479 --- /dev/null +++ b/queue-4.9/rds-fix-two-rcu-related-problems.patch @@ -0,0 +1,62 @@ +From foo@baz Thu Sep 20 09:30:23 CEST 2018 +From: Cong Wang +Date: Mon, 10 Sep 2018 18:27:26 -0700 +Subject: rds: fix two RCU related problems + +From: Cong Wang + +[ Upstream commit cc4dfb7f70a344f24c1c71e298deea0771dadcb2 ] + +When a rds sock is bound, it is inserted into the bind_hash_table +which is protected by RCU. But when releasing rds sock, after it +is removed from this hash table, it is freed immediately without +respecting RCU grace period. This could cause some use-after-free +as reported by syzbot. + +Mark the rds sock with SOCK_RCU_FREE before inserting it into the +bind_hash_table, so that it would be always freed after a RCU grace +period. + +The other problem is in rds_find_bound(), the rds sock could be +freed in between rhashtable_lookup_fast() and rds_sock_addref(), +so we need to extend RCU read lock protection in rds_find_bound() +to close this race condition. + +Reported-and-tested-by: syzbot+8967084bcac563795dc6@syzkaller.appspotmail.com +Reported-by: syzbot+93a5839deb355537440f@syzkaller.appspotmail.com +Cc: Sowmini Varadhan +Cc: Santosh Shilimkar +Cc: rds-devel@oss.oracle.com +Signed-off-by: Cong Wang +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/bind.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/rds/bind.c ++++ b/net/rds/bind.c +@@ -60,11 +60,13 @@ struct rds_sock *rds_find_bound(__be32 a + u64 key = ((u64)addr << 32) | port; + struct rds_sock *rs; + +- rs = rhashtable_lookup_fast(&bind_hash_table, &key, ht_parms); ++ rcu_read_lock(); ++ rs = rhashtable_lookup(&bind_hash_table, &key, ht_parms); + if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) + rds_sock_addref(rs); + else + rs = NULL; ++ rcu_read_unlock(); + + rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr, + ntohs(port)); +@@ -157,6 +159,7 @@ int rds_bind(struct socket *sock, struct + goto out; + } + ++ sock_set_flag(sk, SOCK_RCU_FREE); + ret = rds_add_bound(rs, sin->sin_addr.s_addr, &sin->sin_port); + if (ret) + goto out; diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..b5d7000690f --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,4 @@ +be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch +rds-fix-two-rcu-related-problems.patch +net-mlx5-fix-use-after-free-in-self-healing-flow.patch +net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch -- 2.47.3