From 4a9baf45fd72615a804947a8495b73c4a0a4cb54 Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Fri, 23 Oct 2020 20:48:28 +0200 Subject: net/smc: fix null pointer dereference in smc_listen_decline() smc_listen_work() calls smc_listen_decline() on label out_decl, providing the ini pointer variable. But this pointer can still be null when the label out_decl is reached. Fix this by checking the ini variable in smc_listen_work() and call smc_listen_decline() with the result directly. Fixes: a7c9c5f4af7f ("net/smc: CLC accept / confirm V2") Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/af_smc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'net/smc') diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 82be0bd0f6e8..e9f487c8c6d5 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1317,10 +1317,10 @@ static void smc_listen_out_err(struct smc_sock *new_smc) /* listen worker: decline and fall back if possible */ static void smc_listen_decline(struct smc_sock *new_smc, int reason_code, - struct smc_init_info *ini, u8 version) + int local_first, u8 version) { /* RDMA setup failed, switch back to TCP */ - if (ini->first_contact_local) + if (local_first) smc_lgr_cleanup_early(&new_smc->conn); else smc_conn_free(&new_smc->conn); @@ -1768,7 +1768,8 @@ static void smc_listen_work(struct work_struct *work) out_unlock: mutex_unlock(&smc_server_lgr_pending); out_decl: - smc_listen_decline(new_smc, rc, ini, version); + smc_listen_decline(new_smc, rc, ini ? ini->first_contact_local : 0, + version); out_free: kfree(ini); kfree(buf); -- cgit v1.2.3-70-g09d2 From 96d6fded958d971a3695009e0ed43aca6c598283 Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Fri, 23 Oct 2020 20:48:29 +0200 Subject: net/smc: fix suppressed return code The patch that repaired the invalid return code in smcd_new_buf_create() missed to take care of errno ENOSPC which has a special meaning that no more DMBEs can be registered on the device. Fix that by keeping this errno value during the translation of the return code. Fixes: 6b1bbf94ab36 ("net/smc: fix invalid return code in smcd_new_buf_create()") Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/smc_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'net/smc') diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index d790c43c473f..2b19863f7171 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -1615,8 +1615,11 @@ static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr, rc = smc_ism_register_dmb(lgr, bufsize, buf_desc); if (rc) { kfree(buf_desc); - return (rc == -ENOMEM) ? ERR_PTR(-EAGAIN) : - ERR_PTR(-EIO); + if (rc == -ENOMEM) + return ERR_PTR(-EAGAIN); + if (rc == -ENOSPC) + return ERR_PTR(-ENOSPC); + return ERR_PTR(-EIO); } buf_desc->pages = virt_to_page(buf_desc->cpu_addr); /* CDC header stored in buf. So, pretend it was smaller */ -- cgit v1.2.3-70-g09d2 From 7206d58a3a538c80b36305d1904de313cf47ef4c Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 27 Oct 2020 01:33:56 -0500 Subject: net/smc: Replace zero-length array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.9/process/deprecated.html#zero-length-and-one-element-arrays Signed-off-by: Gustavo A. R. Silva --- net/smc/smc_clc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/smc') diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h index b3f46ab79e47..c579d1d5995a 100644 --- a/net/smc/smc_clc.h +++ b/net/smc/smc_clc.h @@ -124,7 +124,7 @@ struct smc_clc_v2_extension { struct smc_clnt_opts_area_hdr hdr; u8 roce[16]; /* RoCEv2 GID */ u8 reserved[16]; - u8 user_eids[0][SMC_MAX_EID_LEN]; + u8 user_eids[][SMC_MAX_EID_LEN]; }; struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/ @@ -143,7 +143,7 @@ struct smc_clc_msg_smcd { /* SMC-D GID information */ struct smc_clc_smcd_v2_extension { u8 system_eid[SMC_MAX_EID_LEN]; u8 reserved[16]; - struct smc_clc_smcd_gid_chid gidchid[0]; + struct smc_clc_smcd_gid_chid gidchid[]; }; struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */ -- cgit v1.2.3-70-g09d2 From 0530bd6e6a3d5a0292a1a5f33ea980ae7e8b56ca Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Wed, 18 Nov 2020 22:40:37 +0100 Subject: net/smc: fix matching of existing link groups With the multi-subnet support of SMC-Dv2 the match for existing link groups should not include the vlanid of the network device. Set ini->smcd_version accordingly before the call to smc_conn_create() and use this value in smc_conn_create() to skip the vlanid check. Fixes: 5c21c4ccafe8 ("net/smc: determine accepted ISM devices") Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/af_smc.c | 3 ++- net/smc/smc_core.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'net/smc') diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index e9f487c8c6d5..5dd4faaf7d6e 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -979,7 +979,8 @@ static int __smc_connect(struct smc_sock *smc) /* check if smc modes and versions of CLC proposal and accept match */ rc = smc_connect_check_aclc(ini, aclc); - version = aclc->hdr.version == SMC_V1 ? SMC_V1 : version; + version = aclc->hdr.version == SMC_V1 ? SMC_V1 : SMC_V2; + ini->smcd_version = version; if (rc) goto vlan_cleanup; diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 2b19863f7171..af96f813c075 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -1309,7 +1309,8 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini) ini->ism_peer_gid[ini->ism_selected]) : smcr_lgr_match(lgr, ini->ib_lcl, role, ini->ib_clcqpn)) && !lgr->sync_err && - lgr->vlan_id == ini->vlan_id && + (ini->smcd_version == SMC_V2 || + lgr->vlan_id == ini->vlan_id) && (role == SMC_CLNT || ini->is_smcd || lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) { /* link group found */ -- cgit v1.2.3-70-g09d2 From 41a0be3f8f6be893860b991eb10c47fc3ee09d7f Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Wed, 18 Nov 2020 22:40:38 +0100 Subject: net/smc: fix direct access to ib_gid_addr->ndev in smc_ib_determine_gid() Sparse complaints 3 times about: net/smc/smc_ib.c:203:52: warning: incorrect type in argument 1 (different address spaces) net/smc/smc_ib.c:203:52: expected struct net_device const *dev net/smc/smc_ib.c:203:52: got struct net_device [noderef] __rcu *const ndev Fix that by using the existing and validated ndev variable instead of accessing attr->ndev directly. Fixes: 5102eca9039b ("net/smc: Use rdma_read_gid_l2_fields to L2 fields") Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/smc_ib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/smc') diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index 1c314dbdc7fa..fc766b537ac7 100644 --- a/net/smc/smc_ib.c +++ b/net/smc/smc_ib.c @@ -198,9 +198,9 @@ int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport, rcu_read_lock(); ndev = rdma_read_gid_attr_ndev_rcu(attr); if (!IS_ERR(ndev) && - ((!vlan_id && !is_vlan_dev(attr->ndev)) || - (vlan_id && is_vlan_dev(attr->ndev) && - vlan_dev_vlan_id(attr->ndev) == vlan_id)) && + ((!vlan_id && !is_vlan_dev(ndev)) || + (vlan_id && is_vlan_dev(ndev) && + vlan_dev_vlan_id(ndev) == vlan_id)) && attr->gid_type == IB_GID_TYPE_ROCE) { rcu_read_unlock(); if (gid) -- cgit v1.2.3-70-g09d2