From 3d51097d2721495df7fcfcc46e6fcd9f816f6218 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Sep 2018 07:25:03 +0200 Subject: [PATCH] 4.18-stable patches added patches: be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch erspan-fix-error-handling-for-erspan-tunnel.patch erspan-return-packet_reject-when-the-appropriate-tunnel-is-not-found.patch net-mlx5-check-for-error-in-mlx5_attach_interface.patch net-mlx5-e-switch-fix-memory-leak-when-creating-switchdev-mode-fdb-tables.patch net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch net-mlx5-fix-not-releasing-read-lock-when-adding-flow-rules.patch net-mlx5-fix-possible-deadlock-from-lockdep-when-adding-fte-to-fg.patch net-mlx5-fix-use-after-free-in-self-healing-flow.patch net-mlx5-use-u16-for-work-queue-buffer-fragment-size.patch net-qca_spi-fix-race-condition-in-spi-transfers.patch net-tls-set-count-of-sg-entries-if-sk_alloc_sg-returns-enospc.patch rds-fix-two-rcu-related-problems.patch tcp-really-ignore-msg_zerocopy-if-no-so_zerocopy.patch tipc-orphan-sock-in-tipc_release.patch --- ...ry-leak-in-be_cmd_get_profile_config.patch | 31 ++ ...fix-error-handling-for-erspan-tunnel.patch | 34 ++ ...-the-appropriate-tunnel-is-not-found.patch | 33 ++ ...k-for-error-in-mlx5_attach_interface.patch | 59 ++++ ...n-creating-switchdev-mode-fdb-tables.patch | 31 ++ ...eanup-in-the-device-init-remove-flow.patch | 55 +++ ...ing-read-lock-when-adding-flow-rules.patch | 33 ++ ...k-from-lockdep-when-adding-fte-to-fg.patch | 157 +++++++++ ...-use-after-free-in-self-healing-flow.patch | 91 +++++ ...-for-work-queue-buffer-fragment-size.patch | 62 ++++ ...-fix-race-condition-in-spi-transfers.patch | 332 ++++++++++++++++++ ...ntries-if-sk_alloc_sg-returns-enospc.patch | 48 +++ .../rds-fix-two-rcu-related-problems.patch | 62 ++++ ...gnore-msg_zerocopy-if-no-so_zerocopy.patch | 53 +++ .../tipc-orphan-sock-in-tipc_release.patch | 36 ++ 15 files changed, 1117 insertions(+) create mode 100644 queue-4.18/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch create mode 100644 queue-4.18/erspan-fix-error-handling-for-erspan-tunnel.patch create mode 100644 queue-4.18/erspan-return-packet_reject-when-the-appropriate-tunnel-is-not-found.patch create mode 100644 queue-4.18/net-mlx5-check-for-error-in-mlx5_attach_interface.patch create mode 100644 queue-4.18/net-mlx5-e-switch-fix-memory-leak-when-creating-switchdev-mode-fdb-tables.patch create mode 100644 queue-4.18/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch create mode 100644 queue-4.18/net-mlx5-fix-not-releasing-read-lock-when-adding-flow-rules.patch create mode 100644 queue-4.18/net-mlx5-fix-possible-deadlock-from-lockdep-when-adding-fte-to-fg.patch create mode 100644 queue-4.18/net-mlx5-fix-use-after-free-in-self-healing-flow.patch create mode 100644 queue-4.18/net-mlx5-use-u16-for-work-queue-buffer-fragment-size.patch create mode 100644 queue-4.18/net-qca_spi-fix-race-condition-in-spi-transfers.patch create mode 100644 queue-4.18/net-tls-set-count-of-sg-entries-if-sk_alloc_sg-returns-enospc.patch create mode 100644 queue-4.18/rds-fix-two-rcu-related-problems.patch create mode 100644 queue-4.18/tcp-really-ignore-msg_zerocopy-if-no-so_zerocopy.patch create mode 100644 queue-4.18/tipc-orphan-sock-in-tipc_release.patch diff --git a/queue-4.18/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch b/queue-4.18/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch new file mode 100644 index 00000000000..b73081bd94f --- /dev/null +++ b/queue-4.18/be2net-fix-memory-leak-in-be_cmd_get_profile_config.patch @@ -0,0 +1,31 @@ +From foo@baz Thu Sep 20 07:23:37 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.18/erspan-fix-error-handling-for-erspan-tunnel.patch b/queue-4.18/erspan-fix-error-handling-for-erspan-tunnel.patch new file mode 100644 index 00000000000..7a251816f46 --- /dev/null +++ b/queue-4.18/erspan-fix-error-handling-for-erspan-tunnel.patch @@ -0,0 +1,34 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Haishuang Yan +Date: Mon, 10 Sep 2018 22:19:48 +0800 +Subject: erspan: fix error handling for erspan tunnel + +From: Haishuang Yan + +[ Upstream commit 51dc63e3911fbb1f0a7a32da2fe56253e2040ea4 ] + +When processing icmp unreachable message for erspan tunnel, tunnel id +should be erspan_net_id instead of ipgre_net_id. + +Fixes: 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN") +Cc: William Tu +Signed-off-by: Haishuang Yan +Acked-by: William Tu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_gre.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -178,6 +178,9 @@ static void ipgre_err(struct sk_buff *sk + + if (tpi->proto == htons(ETH_P_TEB)) + itn = net_generic(net, gre_tap_net_id); ++ else if (tpi->proto == htons(ETH_P_ERSPAN) || ++ tpi->proto == htons(ETH_P_ERSPAN2)) ++ itn = net_generic(net, erspan_net_id); + else + itn = net_generic(net, ipgre_net_id); + diff --git a/queue-4.18/erspan-return-packet_reject-when-the-appropriate-tunnel-is-not-found.patch b/queue-4.18/erspan-return-packet_reject-when-the-appropriate-tunnel-is-not-found.patch new file mode 100644 index 00000000000..1fe7b080bf6 --- /dev/null +++ b/queue-4.18/erspan-return-packet_reject-when-the-appropriate-tunnel-is-not-found.patch @@ -0,0 +1,33 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Haishuang Yan +Date: Mon, 10 Sep 2018 22:19:47 +0800 +Subject: erspan: return PACKET_REJECT when the appropriate tunnel is not found + +From: Haishuang Yan + +[ Upstream commit 5a64506b5c2c3cdb29d817723205330378075448 ] + +If erspan tunnel hasn't been established, we'd better send icmp port +unreachable message after receive erspan packets. + +Fixes: 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN") +Cc: William Tu +Signed-off-by: Haishuang Yan +Acked-by: William Tu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_gre.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -331,6 +331,8 @@ static int erspan_rcv(struct sk_buff *sk + ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); + return PACKET_RCVD; + } ++ return PACKET_REJECT; ++ + drop: + kfree_skb(skb); + return PACKET_RCVD; diff --git a/queue-4.18/net-mlx5-check-for-error-in-mlx5_attach_interface.patch b/queue-4.18/net-mlx5-check-for-error-in-mlx5_attach_interface.patch new file mode 100644 index 00000000000..f12fc4f19f5 --- /dev/null +++ b/queue-4.18/net-mlx5-check-for-error-in-mlx5_attach_interface.patch @@ -0,0 +1,59 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Huy Nguyen +Date: Wed, 15 Aug 2018 11:08:48 -0500 +Subject: net/mlx5: Check for error in mlx5_attach_interface + +From: Huy Nguyen + +[ Upstream commit 47bc94b82291e007da61ee1b3d18c77871f3e158 ] + +Currently, mlx5_attach_interface does not check for error +after calling intf->attach or intf->add. When these two calls +fails, the client is not initialized and will cause issues such as +kernel panic on invalid address in the teardown path (mlx5_detach_interface) + +Fixes: 737a234bb638 ("net/mlx5: Introduce attach/detach to interface API") +Signed-off-by: Huy Nguyen +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/dev.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c +@@ -132,11 +132,11 @@ void mlx5_add_device(struct mlx5_interfa + delayed_event_start(priv); + + dev_ctx->context = intf->add(dev); +- set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state); +- if (intf->attach) +- set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state); +- + if (dev_ctx->context) { ++ set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state); ++ if (intf->attach) ++ set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state); ++ + spin_lock_irq(&priv->ctx_lock); + list_add_tail(&dev_ctx->list, &priv->ctx_list); + +@@ -211,12 +211,17 @@ static void mlx5_attach_interface(struct + if (intf->attach) { + if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state)) + goto out; +- intf->attach(dev, dev_ctx->context); ++ if (intf->attach(dev, dev_ctx->context)) ++ goto out; ++ + set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state); + } else { + if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state)) + goto out; + dev_ctx->context = intf->add(dev); ++ if (!dev_ctx->context) ++ goto out; ++ + set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state); + } + diff --git a/queue-4.18/net-mlx5-e-switch-fix-memory-leak-when-creating-switchdev-mode-fdb-tables.patch b/queue-4.18/net-mlx5-e-switch-fix-memory-leak-when-creating-switchdev-mode-fdb-tables.patch new file mode 100644 index 00000000000..ff5155f1ddc --- /dev/null +++ b/queue-4.18/net-mlx5-e-switch-fix-memory-leak-when-creating-switchdev-mode-fdb-tables.patch @@ -0,0 +1,31 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Raed Salem +Date: Tue, 21 Aug 2018 15:22:42 +0300 +Subject: net/mlx5: E-Switch, Fix memory leak when creating switchdev mode FDB tables + +From: Raed Salem + +[ Upstream commit c88a026e01219488e745f4f0267fd76c2bb68421 ] + +The memory allocated for the slow path table flow group input structure +was not freed upon successful return, fix that. + +Fixes: 1967ce6ea5c8 ("net/mlx5: E-Switch, Refactor fast path FDB table creation in switchdev mode") +Signed-off-by: Raed Salem +Reviewed-by: Or Gerlitz +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -658,6 +658,7 @@ static int esw_create_offloads_fdb_table + if (err) + goto miss_rule_err; + ++ kvfree(flow_group_in); + return 0; + + miss_rule_err: diff --git a/queue-4.18/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch b/queue-4.18/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch new file mode 100644 index 00000000000..c842cf9ab50 --- /dev/null +++ b/queue-4.18/net-mlx5-fix-debugfs-cleanup-in-the-device-init-remove-flow.patch @@ -0,0 +1,55 @@ +From foo@baz Thu Sep 20 07:23:37 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 +@@ -874,8 +874,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) { +@@ -924,7 +926,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.18/net-mlx5-fix-not-releasing-read-lock-when-adding-flow-rules.patch b/queue-4.18/net-mlx5-fix-not-releasing-read-lock-when-adding-flow-rules.patch new file mode 100644 index 00000000000..99022d73af3 --- /dev/null +++ b/queue-4.18/net-mlx5-fix-not-releasing-read-lock-when-adding-flow-rules.patch @@ -0,0 +1,33 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Roi Dayan +Date: Sun, 19 Aug 2018 08:56:09 +0300 +Subject: net/mlx5: Fix not releasing read lock when adding flow rules + +From: Roi Dayan + +[ Upstream commit 071304772fc747d5df13c51f1cf48a4b922a5e0d ] + +If building match list fg fails and we never jumped to +search_again_locked label then the function returned without +unlocking the read lock. + +Fixes: bd71b08ec2ee ("net/mlx5: Support multiple updates of steering rules in parallel") +Signed-off-by: Roi Dayan +Reviewed-by: Maor Gottlieb +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -1797,6 +1797,8 @@ search_again_locked: + if (err) { + if (take_write) + up_write_ref_node(&ft->node); ++ else ++ up_read_ref_node(&ft->node); + return ERR_PTR(err); + } + diff --git a/queue-4.18/net-mlx5-fix-possible-deadlock-from-lockdep-when-adding-fte-to-fg.patch b/queue-4.18/net-mlx5-fix-possible-deadlock-from-lockdep-when-adding-fte-to-fg.patch new file mode 100644 index 00000000000..eb8703aa63b --- /dev/null +++ b/queue-4.18/net-mlx5-fix-possible-deadlock-from-lockdep-when-adding-fte-to-fg.patch @@ -0,0 +1,157 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Roi Dayan +Date: Mon, 20 Aug 2018 11:43:03 +0300 +Subject: net/mlx5: Fix possible deadlock from lockdep when adding fte to fg + +From: Roi Dayan + +[ Upstream commit ad9421e36a77056a4f095d49b9605e80b4d216ed ] + +This is a false positive report due to incorrect nested lock +annotations as we lock multiple fgs with the same subclass. +Instead of locking all fgs only lock the one being used as was +done before. + +Fixes: bd71b08ec2ee ("net/mlx5: Support multiple updates of steering rules in parallel") +Signed-off-by: Roi Dayan +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 74 +++++++++++----------- + 1 file changed, 37 insertions(+), 37 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -1649,6 +1649,33 @@ static u64 matched_fgs_get_version(struc + return version; + } + ++static struct fs_fte * ++lookup_fte_locked(struct mlx5_flow_group *g, ++ u32 *match_value, ++ bool take_write) ++{ ++ struct fs_fte *fte_tmp; ++ ++ if (take_write) ++ nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); ++ else ++ nested_down_read_ref_node(&g->node, FS_LOCK_PARENT); ++ fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, ++ rhash_fte); ++ if (!fte_tmp || !tree_get_node(&fte_tmp->node)) { ++ fte_tmp = NULL; ++ goto out; ++ } ++ ++ nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); ++out: ++ if (take_write) ++ up_write_ref_node(&g->node); ++ else ++ up_read_ref_node(&g->node); ++ return fte_tmp; ++} ++ + static struct mlx5_flow_handle * + try_add_to_existing_fg(struct mlx5_flow_table *ft, + struct list_head *match_head, +@@ -1671,10 +1698,6 @@ try_add_to_existing_fg(struct mlx5_flow_ + if (IS_ERR(fte)) + return ERR_PTR(-ENOMEM); + +- list_for_each_entry(iter, match_head, list) { +- nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT); +- } +- + search_again_locked: + version = matched_fgs_get_version(match_head); + /* Try to find a fg that already contains a matching fte */ +@@ -1682,20 +1705,9 @@ search_again_locked: + struct fs_fte *fte_tmp; + + g = iter->g; +- fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, spec->match_value, +- rhash_fte); +- if (!fte_tmp || !tree_get_node(&fte_tmp->node)) ++ fte_tmp = lookup_fte_locked(g, spec->match_value, take_write); ++ if (!fte_tmp) + continue; +- +- nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); +- if (!take_write) { +- list_for_each_entry(iter, match_head, list) +- up_read_ref_node(&iter->g->node); +- } else { +- list_for_each_entry(iter, match_head, list) +- up_write_ref_node(&iter->g->node); +- } +- + rule = add_rule_fg(g, spec->match_value, + flow_act, dest, dest_num, fte_tmp); + up_write_ref_node(&fte_tmp->node); +@@ -1704,19 +1716,6 @@ search_again_locked: + return rule; + } + +- /* No group with matching fte found. Try to add a new fte to any +- * matching fg. +- */ +- +- if (!take_write) { +- list_for_each_entry(iter, match_head, list) +- up_read_ref_node(&iter->g->node); +- list_for_each_entry(iter, match_head, list) +- nested_down_write_ref_node(&iter->g->node, +- FS_LOCK_PARENT); +- take_write = true; +- } +- + /* Check the ft version, for case that new flow group + * was added while the fgs weren't locked + */ +@@ -1728,27 +1727,30 @@ search_again_locked: + /* Check the fgs version, for case the new FTE with the + * same values was added while the fgs weren't locked + */ +- if (version != matched_fgs_get_version(match_head)) ++ if (version != matched_fgs_get_version(match_head)) { ++ take_write = true; + goto search_again_locked; ++ } + + list_for_each_entry(iter, match_head, list) { + g = iter->g; + + if (!g->node.active) + continue; ++ ++ nested_down_write_ref_node(&g->node, FS_LOCK_PARENT); ++ + err = insert_fte(g, fte); + if (err) { ++ up_write_ref_node(&g->node); + if (err == -ENOSPC) + continue; +- list_for_each_entry(iter, match_head, list) +- up_write_ref_node(&iter->g->node); + kmem_cache_free(steering->ftes_cache, fte); + return ERR_PTR(err); + } + + nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD); +- list_for_each_entry(iter, match_head, list) +- up_write_ref_node(&iter->g->node); ++ up_write_ref_node(&g->node); + rule = add_rule_fg(g, spec->match_value, + flow_act, dest, dest_num, fte); + up_write_ref_node(&fte->node); +@@ -1757,8 +1759,6 @@ search_again_locked: + } + rule = ERR_PTR(-ENOENT); + out: +- list_for_each_entry(iter, match_head, list) +- up_write_ref_node(&iter->g->node); + kmem_cache_free(steering->ftes_cache, fte); + return rule; + } diff --git a/queue-4.18/net-mlx5-fix-use-after-free-in-self-healing-flow.patch b/queue-4.18/net-mlx5-fix-use-after-free-in-self-healing-flow.patch new file mode 100644 index 00000000000..2300f64b1a8 --- /dev/null +++ b/queue-4.18/net-mlx5-fix-use-after-free-in-self-healing-flow.patch @@ -0,0 +1,91 @@ +From foo@baz Thu Sep 20 07:23:37 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 | 6 +++--- + include/linux/mlx5/driver.h | 2 +- + 3 files changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -331,9 +331,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 +@@ -1266,7 +1266,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; +@@ -1325,7 +1325,7 @@ static int mlx5_unload_one(struct mlx5_c + mlx5_free_irq_vectors(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"); +@@ -1587,7 +1587,7 @@ static int mlx5_try_fast_unload(struct m + * with the HCA, so the health polll is no longer needed. + */ + mlx5_drain_health_wq(dev); +- mlx5_stop_health_poll(dev); ++ mlx5_stop_health_poll(dev, false); + + ret = mlx5_cmd_force_teardown_hca(dev); + if (ret) { +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1042,7 +1042,7 @@ int mlx5_cmd_free_uar(struct mlx5_core_d + 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_trigger_health_work(struct mlx5_core_dev *dev); + void mlx5_drain_health_recovery(struct mlx5_core_dev *dev); diff --git a/queue-4.18/net-mlx5-use-u16-for-work-queue-buffer-fragment-size.patch b/queue-4.18/net-mlx5-use-u16-for-work-queue-buffer-fragment-size.patch new file mode 100644 index 00000000000..cb1710130c4 --- /dev/null +++ b/queue-4.18/net-mlx5-use-u16-for-work-queue-buffer-fragment-size.patch @@ -0,0 +1,62 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Tariq Toukan +Date: Tue, 21 Aug 2018 16:04:41 +0300 +Subject: net/mlx5: Use u16 for Work Queue buffer fragment size + +From: Tariq Toukan + +[ Upstream commit 8d71e818506718e8d7032ce824b5c74a17d4f7a5 ] + +Minimal stride size is 16. +Hence, the number of strides in a fragment (of PAGE_SIZE) +is <= PAGE_SIZE / 16 <= 4K. + +u16 is sufficient to represent this. + +Fixes: 388ca8be0037 ("IB/mlx5: Implement fragmented completion queue (CQ)") +Signed-off-by: Tariq Toukan +Reviewed-by: Eran Ben Elisha +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/wq.c | 4 ++-- + drivers/net/ethernet/mellanox/mlx5/core/wq.h | 2 +- + include/linux/mlx5/driver.h | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.c +@@ -39,9 +39,9 @@ u32 mlx5_wq_cyc_get_size(struct mlx5_wq_ + return (u32)wq->fbc.sz_m1 + 1; + } + +-u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq) ++u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq) + { +- return (u32)wq->fbc.frag_sz_m1 + 1; ++ return wq->fbc.frag_sz_m1 + 1; + } + + u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) +--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.h +@@ -80,7 +80,7 @@ int mlx5_wq_cyc_create(struct mlx5_core_ + void *wqc, struct mlx5_wq_cyc *wq, + struct mlx5_wq_ctrl *wq_ctrl); + u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq); +-u32 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq); ++u16 mlx5_wq_cyc_get_frag_size(struct mlx5_wq_cyc *wq); + + int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, + void *qpc, struct mlx5_wq_qp *wq, +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -357,7 +357,7 @@ struct mlx5_frag_buf { + struct mlx5_frag_buf_ctrl { + struct mlx5_frag_buf frag_buf; + u32 sz_m1; +- u32 frag_sz_m1; ++ u16 frag_sz_m1; + u32 strides_offset; + u8 log_sz; + u8 log_stride; diff --git a/queue-4.18/net-qca_spi-fix-race-condition-in-spi-transfers.patch b/queue-4.18/net-qca_spi-fix-race-condition-in-spi-transfers.patch new file mode 100644 index 00000000000..c69603eba14 --- /dev/null +++ b/queue-4.18/net-qca_spi-fix-race-condition-in-spi-transfers.patch @@ -0,0 +1,332 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Stefan Wahren +Date: Wed, 5 Sep 2018 15:23:18 +0200 +Subject: net: qca_spi: Fix race condition in spi transfers + +From: Stefan Wahren + +[ Upstream commit e65a9e480e91ddf9e15155454d370cead64689c8 ] + +With performance optimization the spi transfer and messages of basic +register operations like qcaspi_read_register moved into the private +driver structure. But they weren't protected against mutual access +(e.g. between driver kthread and ethtool). So dumping the QCA7000 +registers via ethtool during network traffic could make spi_sync +hang forever, because the completion in spi_message is overwritten. + +So revert the optimization completely. + +Fixes: 291ab06ecf676 ("net: qualcomm: new Ethernet over SPI driver for QCA700") +Signed-off-by: Stefan Wahren +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qualcomm/qca_7k.c | 76 ++++++++++----------- + drivers/net/ethernet/qualcomm/qca_spi.c | 114 ++++++++++++++++---------------- + drivers/net/ethernet/qualcomm/qca_spi.h | 5 - + 3 files changed, 95 insertions(+), 100 deletions(-) + +--- a/drivers/net/ethernet/qualcomm/qca_7k.c ++++ b/drivers/net/ethernet/qualcomm/qca_7k.c +@@ -45,34 +45,33 @@ qcaspi_read_register(struct qcaspi *qca, + { + __be16 rx_data; + __be16 tx_data; +- struct spi_transfer *transfer; +- struct spi_message *msg; ++ struct spi_transfer transfer[2]; ++ struct spi_message msg; + int ret; + ++ memset(transfer, 0, sizeof(transfer)); ++ ++ spi_message_init(&msg); ++ + tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg); ++ *result = 0; ++ ++ transfer[0].tx_buf = &tx_data; ++ transfer[0].len = QCASPI_CMD_LEN; ++ transfer[1].rx_buf = &rx_data; ++ transfer[1].len = QCASPI_CMD_LEN; ++ ++ spi_message_add_tail(&transfer[0], &msg); + + if (qca->legacy_mode) { +- msg = &qca->spi_msg1; +- transfer = &qca->spi_xfer1; +- transfer->tx_buf = &tx_data; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- spi_sync(qca->spi_dev, msg); +- } else { +- msg = &qca->spi_msg2; +- transfer = &qca->spi_xfer2[0]; +- transfer->tx_buf = &tx_data; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- transfer = &qca->spi_xfer2[1]; ++ spi_sync(qca->spi_dev, &msg); ++ spi_message_init(&msg); + } +- transfer->tx_buf = NULL; +- transfer->rx_buf = &rx_data; +- transfer->len = QCASPI_CMD_LEN; +- ret = spi_sync(qca->spi_dev, msg); ++ spi_message_add_tail(&transfer[1], &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + + if (!ret) +- ret = msg->status; ++ ret = msg.status; + + if (ret) + qcaspi_spi_error(qca); +@@ -86,35 +85,32 @@ int + qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value) + { + __be16 tx_data[2]; +- struct spi_transfer *transfer; +- struct spi_message *msg; ++ struct spi_transfer transfer[2]; ++ struct spi_message msg; + int ret; + ++ memset(&transfer, 0, sizeof(transfer)); ++ ++ spi_message_init(&msg); ++ + tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg); + tx_data[1] = cpu_to_be16(value); + ++ transfer[0].tx_buf = &tx_data[0]; ++ transfer[0].len = QCASPI_CMD_LEN; ++ transfer[1].tx_buf = &tx_data[1]; ++ transfer[1].len = QCASPI_CMD_LEN; ++ ++ spi_message_add_tail(&transfer[0], &msg); + if (qca->legacy_mode) { +- msg = &qca->spi_msg1; +- transfer = &qca->spi_xfer1; +- transfer->tx_buf = &tx_data[0]; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- spi_sync(qca->spi_dev, msg); +- } else { +- msg = &qca->spi_msg2; +- transfer = &qca->spi_xfer2[0]; +- transfer->tx_buf = &tx_data[0]; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- transfer = &qca->spi_xfer2[1]; ++ spi_sync(qca->spi_dev, &msg); ++ spi_message_init(&msg); + } +- transfer->tx_buf = &tx_data[1]; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- ret = spi_sync(qca->spi_dev, msg); ++ spi_message_add_tail(&transfer[1], &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + + if (!ret) +- ret = msg->status; ++ ret = msg.status; + + if (ret) + qcaspi_spi_error(qca); +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -99,22 +99,24 @@ static u32 + qcaspi_write_burst(struct qcaspi *qca, u8 *src, u32 len) + { + __be16 cmd; +- struct spi_message *msg = &qca->spi_msg2; +- struct spi_transfer *transfer = &qca->spi_xfer2[0]; ++ struct spi_message msg; ++ struct spi_transfer transfer[2]; + int ret; + +- cmd = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL); +- transfer->tx_buf = &cmd; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- transfer = &qca->spi_xfer2[1]; +- transfer->tx_buf = src; +- transfer->rx_buf = NULL; +- transfer->len = len; ++ memset(&transfer, 0, sizeof(transfer)); ++ spi_message_init(&msg); + +- ret = spi_sync(qca->spi_dev, msg); ++ cmd = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL); ++ transfer[0].tx_buf = &cmd; ++ transfer[0].len = QCASPI_CMD_LEN; ++ transfer[1].tx_buf = src; ++ transfer[1].len = len; ++ ++ spi_message_add_tail(&transfer[0], &msg); ++ spi_message_add_tail(&transfer[1], &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + +- if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) { ++ if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) { + qcaspi_spi_error(qca); + return 0; + } +@@ -125,17 +127,20 @@ qcaspi_write_burst(struct qcaspi *qca, u + static u32 + qcaspi_write_legacy(struct qcaspi *qca, u8 *src, u32 len) + { +- struct spi_message *msg = &qca->spi_msg1; +- struct spi_transfer *transfer = &qca->spi_xfer1; ++ struct spi_message msg; ++ struct spi_transfer transfer; + int ret; + +- transfer->tx_buf = src; +- transfer->rx_buf = NULL; +- transfer->len = len; ++ memset(&transfer, 0, sizeof(transfer)); ++ spi_message_init(&msg); ++ ++ transfer.tx_buf = src; ++ transfer.len = len; + +- ret = spi_sync(qca->spi_dev, msg); ++ spi_message_add_tail(&transfer, &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + +- if (ret || (msg->actual_length != len)) { ++ if (ret || (msg.actual_length != len)) { + qcaspi_spi_error(qca); + return 0; + } +@@ -146,23 +151,25 @@ qcaspi_write_legacy(struct qcaspi *qca, + static u32 + qcaspi_read_burst(struct qcaspi *qca, u8 *dst, u32 len) + { +- struct spi_message *msg = &qca->spi_msg2; ++ struct spi_message msg; + __be16 cmd; +- struct spi_transfer *transfer = &qca->spi_xfer2[0]; ++ struct spi_transfer transfer[2]; + int ret; + +- cmd = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL); +- transfer->tx_buf = &cmd; +- transfer->rx_buf = NULL; +- transfer->len = QCASPI_CMD_LEN; +- transfer = &qca->spi_xfer2[1]; +- transfer->tx_buf = NULL; +- transfer->rx_buf = dst; +- transfer->len = len; ++ memset(&transfer, 0, sizeof(transfer)); ++ spi_message_init(&msg); + +- ret = spi_sync(qca->spi_dev, msg); ++ cmd = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL); ++ transfer[0].tx_buf = &cmd; ++ transfer[0].len = QCASPI_CMD_LEN; ++ transfer[1].rx_buf = dst; ++ transfer[1].len = len; ++ ++ spi_message_add_tail(&transfer[0], &msg); ++ spi_message_add_tail(&transfer[1], &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + +- if (ret || (msg->actual_length != QCASPI_CMD_LEN + len)) { ++ if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) { + qcaspi_spi_error(qca); + return 0; + } +@@ -173,17 +180,20 @@ qcaspi_read_burst(struct qcaspi *qca, u8 + static u32 + qcaspi_read_legacy(struct qcaspi *qca, u8 *dst, u32 len) + { +- struct spi_message *msg = &qca->spi_msg1; +- struct spi_transfer *transfer = &qca->spi_xfer1; ++ struct spi_message msg; ++ struct spi_transfer transfer; + int ret; + +- transfer->tx_buf = NULL; +- transfer->rx_buf = dst; +- transfer->len = len; ++ memset(&transfer, 0, sizeof(transfer)); ++ spi_message_init(&msg); ++ ++ transfer.rx_buf = dst; ++ transfer.len = len; + +- ret = spi_sync(qca->spi_dev, msg); ++ spi_message_add_tail(&transfer, &msg); ++ ret = spi_sync(qca->spi_dev, &msg); + +- if (ret || (msg->actual_length != len)) { ++ if (ret || (msg.actual_length != len)) { + qcaspi_spi_error(qca); + return 0; + } +@@ -195,19 +205,23 @@ static int + qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd) + { + __be16 tx_data; +- struct spi_message *msg = &qca->spi_msg1; +- struct spi_transfer *transfer = &qca->spi_xfer1; ++ struct spi_message msg; ++ struct spi_transfer transfer; + int ret; + ++ memset(&transfer, 0, sizeof(transfer)); ++ ++ spi_message_init(&msg); ++ + tx_data = cpu_to_be16(cmd); +- transfer->len = sizeof(tx_data); +- transfer->tx_buf = &tx_data; +- transfer->rx_buf = NULL; ++ transfer.len = sizeof(cmd); ++ transfer.tx_buf = &tx_data; ++ spi_message_add_tail(&transfer, &msg); + +- ret = spi_sync(qca->spi_dev, msg); ++ ret = spi_sync(qca->spi_dev, &msg); + + if (!ret) +- ret = msg->status; ++ ret = msg.status; + + if (ret) + qcaspi_spi_error(qca); +@@ -835,16 +849,6 @@ qcaspi_netdev_setup(struct net_device *d + qca = netdev_priv(dev); + memset(qca, 0, sizeof(struct qcaspi)); + +- memset(&qca->spi_xfer1, 0, sizeof(struct spi_transfer)); +- memset(&qca->spi_xfer2, 0, sizeof(struct spi_transfer) * 2); +- +- spi_message_init(&qca->spi_msg1); +- spi_message_add_tail(&qca->spi_xfer1, &qca->spi_msg1); +- +- spi_message_init(&qca->spi_msg2); +- spi_message_add_tail(&qca->spi_xfer2[0], &qca->spi_msg2); +- spi_message_add_tail(&qca->spi_xfer2[1], &qca->spi_msg2); +- + memset(&qca->txr, 0, sizeof(qca->txr)); + qca->txr.count = TX_RING_MAX_LEN; + } +--- a/drivers/net/ethernet/qualcomm/qca_spi.h ++++ b/drivers/net/ethernet/qualcomm/qca_spi.h +@@ -83,11 +83,6 @@ struct qcaspi { + struct tx_ring txr; + struct qcaspi_stats stats; + +- struct spi_message spi_msg1; +- struct spi_message spi_msg2; +- struct spi_transfer spi_xfer1; +- struct spi_transfer spi_xfer2[2]; +- + u8 *rx_buffer; + u32 buffer_size; + u8 sync; diff --git a/queue-4.18/net-tls-set-count-of-sg-entries-if-sk_alloc_sg-returns-enospc.patch b/queue-4.18/net-tls-set-count-of-sg-entries-if-sk_alloc_sg-returns-enospc.patch new file mode 100644 index 00000000000..0158b24da88 --- /dev/null +++ b/queue-4.18/net-tls-set-count-of-sg-entries-if-sk_alloc_sg-returns-enospc.patch @@ -0,0 +1,48 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Vakul Garg +Date: Thu, 6 Sep 2018 21:41:40 +0530 +Subject: net/tls: Set count of SG entries if sk_alloc_sg returns -ENOSPC + +From: Vakul Garg + +[ Upstream commit 52ea992cfac357b73180d5c051dca43bc8d20c2a ] + +tls_sw_sendmsg() allocates plaintext and encrypted SG entries using +function sk_alloc_sg(). In case the number of SG entries hit +MAX_SKB_FRAGS, sk_alloc_sg() returns -ENOSPC and sets the variable for +current SG index to '0'. This leads to calling of function +tls_push_record() with 'sg_encrypted_num_elem = 0' and later causes +kernel crash. To fix this, set the number of SG elements to the number +of elements in plaintext/encrypted SG arrays in case sk_alloc_sg() +returns -ENOSPC. + +Fixes: 3c4d7559159b ("tls: kernel TLS support") +Signed-off-by: Vakul Garg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -149,6 +149,9 @@ static int alloc_encrypted_sg(struct soc + &ctx->sg_encrypted_num_elem, + &ctx->sg_encrypted_size, 0); + ++ if (rc == -ENOSPC) ++ ctx->sg_encrypted_num_elem = ARRAY_SIZE(ctx->sg_encrypted_data); ++ + return rc; + } + +@@ -162,6 +165,9 @@ static int alloc_plaintext_sg(struct soc + &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size, + tls_ctx->pending_open_record_frags); + ++ if (rc == -ENOSPC) ++ ctx->sg_plaintext_num_elem = ARRAY_SIZE(ctx->sg_plaintext_data); ++ + return rc; + } + diff --git a/queue-4.18/rds-fix-two-rcu-related-problems.patch b/queue-4.18/rds-fix-two-rcu-related-problems.patch new file mode 100644 index 00000000000..79b681a524f --- /dev/null +++ b/queue-4.18/rds-fix-two-rcu-related-problems.patch @@ -0,0 +1,62 @@ +From foo@baz Thu Sep 20 07:23:37 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.18/tcp-really-ignore-msg_zerocopy-if-no-so_zerocopy.patch b/queue-4.18/tcp-really-ignore-msg_zerocopy-if-no-so_zerocopy.patch new file mode 100644 index 00000000000..28ee6a697e9 --- /dev/null +++ b/queue-4.18/tcp-really-ignore-msg_zerocopy-if-no-so_zerocopy.patch @@ -0,0 +1,53 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Vincent Whitchurch +Date: Thu, 6 Sep 2018 15:54:59 +0200 +Subject: tcp: really ignore MSG_ZEROCOPY if no SO_ZEROCOPY + +From: Vincent Whitchurch + +[ Upstream commit 5cf4a8532c992bb22a9ecd5f6d93f873f4eaccc2 ] + +According to the documentation in msg_zerocopy.rst, the SO_ZEROCOPY +flag was introduced because send(2) ignores unknown message flags and +any legacy application which was accidentally passing the equivalent of +MSG_ZEROCOPY earlier should not see any new behaviour. + +Before commit f214f915e7db ("tcp: enable MSG_ZEROCOPY"), a send(2) call +which passed the equivalent of MSG_ZEROCOPY without setting SO_ZEROCOPY +would succeed. However, after that commit, it fails with -ENOBUFS. So +it appears that the SO_ZEROCOPY flag fails to fulfill its intended +purpose. Fix it. + +Fixes: f214f915e7db ("tcp: enable MSG_ZEROCOPY") +Signed-off-by: Vincent Whitchurch +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 3 --- + net/ipv4/tcp.c | 2 +- + 2 files changed, 1 insertion(+), 4 deletions(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -939,9 +939,6 @@ struct ubuf_info *sock_zerocopy_alloc(st + + WARN_ON_ONCE(!in_task()); + +- if (!sock_flag(sk, SOCK_ZEROCOPY)) +- return NULL; +- + skb = sock_omalloc(sk, 0, GFP_KERNEL); + if (!skb) + return NULL; +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1186,7 +1186,7 @@ int tcp_sendmsg_locked(struct sock *sk, + + flags = msg->msg_flags; + +- if (flags & MSG_ZEROCOPY && size) { ++ if (flags & MSG_ZEROCOPY && size && sock_flag(sk, SOCK_ZEROCOPY)) { + if (sk->sk_state != TCP_ESTABLISHED) { + err = -EINVAL; + goto out_err; diff --git a/queue-4.18/tipc-orphan-sock-in-tipc_release.patch b/queue-4.18/tipc-orphan-sock-in-tipc_release.patch new file mode 100644 index 00000000000..d595d3e6501 --- /dev/null +++ b/queue-4.18/tipc-orphan-sock-in-tipc_release.patch @@ -0,0 +1,36 @@ +From foo@baz Thu Sep 20 07:23:37 CEST 2018 +From: Cong Wang +Date: Mon, 3 Sep 2018 19:12:41 -0700 +Subject: tipc: orphan sock in tipc_release() + +From: Cong Wang + +[ Upstream commit 0a3b8b2b215f9e84b82ae97df71292ccfd92b1e7 ] + +Before we unlock the sock in tipc_release(), we have to +detach sk->sk_socket from sk, otherwise a parallel +tipc_sk_fill_sock_diag() could stil read it after we +free this socket. + +Fixes: c30b70deb5f4 ("tipc: implement socket diagnostics for AF_TIPC") +Reported-and-tested-by: syzbot+48804b87c16588ad491d@syzkaller.appspotmail.com +Cc: Jon Maloy +Cc: Ying Xue +Signed-off-by: Cong Wang +Acked-by: Ying Xue +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/socket.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -578,6 +578,7 @@ static int tipc_release(struct socket *s + sk_stop_timer(sk, &sk->sk_timer); + tipc_sk_remove(tsk); + ++ sock_orphan(sk); + /* Reject any messages that accumulated in backlog queue */ + release_sock(sk); + tipc_dest_list_purge(&tsk->cong_links); -- 2.47.3