提交 03e9b33a 编写于 作者: M Md Haris Iqbal 提交者: Jason Gunthorpe

RDMA/rtrs: Only allow addition of path to an already established session

While adding a path from the client side to an already established
session, it was possible to provide the destination IP to a different
server. This is dangerous.

This commit adds an extra member to the rtrs_msg_conn_req structure, named
first_conn; which is supposed to notify if the connection request is the
first for that session or not.

On the server side, if a session does not exist but the first_conn
received inside the rtrs_msg_conn_req structure is 1, the connection
request is failed. This signifies that the connection request is for an
already existing session, and since the server did not find one, it is an
wrong connection request.

Fixes: 6a98d71d ("RDMA/rtrs: client: main functionality")
Fixes: 9cb83748 ("RDMA/rtrs: server: main functionality")
Link: https://lore.kernel.org/r/20210212134525.103456-3-jinpu.wang@cloud.ionos.comSigned-off-by: NMd Haris Iqbal <haris.iqbal@cloud.ionos.com>
Reviewed-by: NLutz Pogrell <lutz.pogrell@cloud.ionos.com>
Signed-off-by: NJack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: NJason Gunthorpe <jgg@nvidia.com>
上级 e6daa8f6
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
*/ */
#define RTRS_RECONNECT_SEED 8 #define RTRS_RECONNECT_SEED 8
#define FIRST_CONN 0x01
MODULE_DESCRIPTION("RDMA Transport Client"); MODULE_DESCRIPTION("RDMA Transport Client");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1660,6 +1662,7 @@ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con) ...@@ -1660,6 +1662,7 @@ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
.cid_num = cpu_to_le16(sess->s.con_num), .cid_num = cpu_to_le16(sess->s.con_num),
.recon_cnt = cpu_to_le16(sess->s.recon_cnt), .recon_cnt = cpu_to_le16(sess->s.recon_cnt),
}; };
msg.first_conn = sess->for_new_clt ? FIRST_CONN : 0;
uuid_copy(&msg.sess_uuid, &sess->s.uuid); uuid_copy(&msg.sess_uuid, &sess->s.uuid);
uuid_copy(&msg.paths_uuid, &clt->paths_uuid); uuid_copy(&msg.paths_uuid, &clt->paths_uuid);
...@@ -1745,6 +1748,8 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, ...@@ -1745,6 +1748,8 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
scnprintf(sess->hca_name, sizeof(sess->hca_name), scnprintf(sess->hca_name, sizeof(sess->hca_name),
sess->s.dev->ib_dev->name); sess->s.dev->ib_dev->name);
sess->s.src_addr = con->c.cm_id->route.addr.src_addr; sess->s.src_addr = con->c.cm_id->route.addr.src_addr;
/* set for_new_clt, to allow future reconnect on any path */
sess->for_new_clt = 1;
} }
return 0; return 0;
...@@ -2662,6 +2667,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops, ...@@ -2662,6 +2667,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
err = PTR_ERR(sess); err = PTR_ERR(sess);
goto close_all_sess; goto close_all_sess;
} }
if (!i)
sess->for_new_clt = 1;
list_add_tail_rcu(&sess->s.entry, &clt->paths_list); list_add_tail_rcu(&sess->s.entry, &clt->paths_list);
err = init_sess(sess); err = init_sess(sess);
......
...@@ -143,6 +143,7 @@ struct rtrs_clt_sess { ...@@ -143,6 +143,7 @@ struct rtrs_clt_sess {
int max_send_sge; int max_send_sge;
u32 flags; u32 flags;
struct kobject kobj; struct kobject kobj;
u8 for_new_clt;
struct rtrs_clt_stats *stats; struct rtrs_clt_stats *stats;
/* cache hca_port and hca_name to display in sysfs */ /* cache hca_port and hca_name to display in sysfs */
u8 hca_port; u8 hca_port;
......
...@@ -188,7 +188,9 @@ struct rtrs_msg_conn_req { ...@@ -188,7 +188,9 @@ struct rtrs_msg_conn_req {
__le16 recon_cnt; __le16 recon_cnt;
uuid_t sess_uuid; uuid_t sess_uuid;
uuid_t paths_uuid; uuid_t paths_uuid;
u8 reserved[12]; u8 first_conn : 1;
u8 reserved_bits : 7;
u8 reserved[11];
}; };
/** /**
......
...@@ -1333,7 +1333,8 @@ static void free_srv(struct rtrs_srv *srv) ...@@ -1333,7 +1333,8 @@ static void free_srv(struct rtrs_srv *srv)
} }
static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx, static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx,
const uuid_t *paths_uuid) const uuid_t *paths_uuid,
bool first_conn)
{ {
struct rtrs_srv *srv; struct rtrs_srv *srv;
int i; int i;
...@@ -1346,12 +1347,20 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx, ...@@ -1346,12 +1347,20 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx,
return srv; return srv;
} }
} }
/*
* If this request is not the first connection request from the
* client for this session then fail and return error.
*/
if (!first_conn) {
mutex_unlock(&ctx->srv_mutex);
return ERR_PTR(-ENXIO);
}
/* need to allocate a new srv */ /* need to allocate a new srv */
srv = kzalloc(sizeof(*srv), GFP_KERNEL); srv = kzalloc(sizeof(*srv), GFP_KERNEL);
if (!srv) { if (!srv) {
mutex_unlock(&ctx->srv_mutex); mutex_unlock(&ctx->srv_mutex);
return NULL; return ERR_PTR(-ENOMEM);
} }
INIT_LIST_HEAD(&srv->paths_list); INIT_LIST_HEAD(&srv->paths_list);
...@@ -1386,7 +1395,7 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx, ...@@ -1386,7 +1395,7 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx,
err_free_srv: err_free_srv:
kfree(srv); kfree(srv);
return NULL; return ERR_PTR(-ENOMEM);
} }
static void put_srv(struct rtrs_srv *srv) static void put_srv(struct rtrs_srv *srv)
...@@ -1787,13 +1796,13 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id, ...@@ -1787,13 +1796,13 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
goto reject_w_econnreset; goto reject_w_econnreset;
} }
recon_cnt = le16_to_cpu(msg->recon_cnt); recon_cnt = le16_to_cpu(msg->recon_cnt);
srv = get_or_create_srv(ctx, &msg->paths_uuid); srv = get_or_create_srv(ctx, &msg->paths_uuid, msg->first_conn);
/* /*
* "refcount == 0" happens if a previous thread calls get_or_create_srv * "refcount == 0" happens if a previous thread calls get_or_create_srv
* allocate srv, but chunks of srv are not allocated yet. * allocate srv, but chunks of srv are not allocated yet.
*/ */
if (!srv || refcount_read(&srv->refcount) == 0) { if (IS_ERR(srv) || refcount_read(&srv->refcount) == 0) {
err = -ENOMEM; err = PTR_ERR(srv);
goto reject_w_err; goto reject_w_err;
} }
mutex_lock(&srv->paths_mutex); mutex_lock(&srv->paths_mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册