RDMA/cma: Fix accessing invalid private data for UD

If a application is using AF_IB with a UD QP, but does not provide any
private data, we will end up accessing invalid memory.  Check for this
case and handle it appropriately.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
Sean Hefty 2013-07-24 15:06:08 -07:00 committed by Roland Dreier
parent 8fb488d740
commit e511d1ae16
1 changed files with 11 additions and 8 deletions

View File

@ -2676,29 +2676,32 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
{
struct ib_cm_sidr_req_param req;
struct ib_cm_id *id;
void *private_data;
int offset, ret;
memset(&req, 0, sizeof req);
offset = cma_user_data_offset(id_priv);
req.private_data_len = offset + conn_param->private_data_len;
if (req.private_data_len < conn_param->private_data_len)
return -EINVAL;
if (req.private_data_len) {
req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
if (!req.private_data)
private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
if (!private_data)
return -ENOMEM;
} else {
req.private_data = NULL;
private_data = NULL;
}
if (conn_param->private_data && conn_param->private_data_len)
memcpy((void *) req.private_data + offset,
conn_param->private_data, conn_param->private_data_len);
memcpy(private_data + offset, conn_param->private_data,
conn_param->private_data_len);
if (req.private_data) {
ret = cma_format_hdr((void *) req.private_data, id_priv);
if (private_data) {
ret = cma_format_hdr(private_data, id_priv);
if (ret)
goto out;
req.private_data = private_data;
}
id = ib_create_cm_id(id_priv->id.device, cma_sidr_rep_handler,
@ -2720,7 +2723,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
id_priv->cm_id.ib = NULL;
}
out:
kfree(req.private_data);
kfree(private_data);
return ret;
}