aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/ib_cm.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 605c032ed5d5..0964ac533ec8 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -98,7 +98,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
98 struct ib_qp_attr qp_attr; 98 struct ib_qp_attr qp_attr;
99 int err; 99 int err;
100 100
101 if (event->param.conn.private_data_len) { 101 if (event->param.conn.private_data_len >= sizeof(*dp)) {
102 dp = event->param.conn.private_data; 102 dp = event->param.conn.private_data;
103 103
104 rds_ib_set_protocol(conn, 104 rds_ib_set_protocol(conn,
@@ -344,19 +344,32 @@ out:
344 return ret; 344 return ret;
345} 345}
346 346
347static u32 rds_ib_protocol_compatible(const struct rds_ib_connect_private *dp) 347static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event)
348{ 348{
349 const struct rds_ib_connect_private *dp = event->param.conn.private_data;
349 u16 common; 350 u16 common;
350 u32 version = 0; 351 u32 version = 0;
351 352
352 /* rdma_cm private data is odd - when there is any private data in the 353 /*
354 * rdma_cm private data is odd - when there is any private data in the
353 * request, we will be given a pretty large buffer without telling us the 355 * request, we will be given a pretty large buffer without telling us the
354 * original size. The only way to tell the difference is by looking at 356 * original size. The only way to tell the difference is by looking at
355 * the contents, which are initialized to zero. 357 * the contents, which are initialized to zero.
356 * If the protocol version fields aren't set, this is a connection attempt 358 * If the protocol version fields aren't set, this is a connection attempt
357 * from an older version. This could could be 3.0 or 2.0 - we can't tell. 359 * from an older version. This could could be 3.0 or 2.0 - we can't tell.
358 * We really should have changed this for OFED 1.3 :-( */ 360 * We really should have changed this for OFED 1.3 :-(
359 if (dp->dp_protocol_major == 0) 361 */
362
363 /* Be paranoid. RDS always has privdata */
364 if (!event->param.conn.private_data_len) {
365 printk(KERN_NOTICE "RDS incoming connection has no private data, "
366 "rejecting\n");
367 return 0;
368 }
369
370 /* Even if len is crap *now* I still want to check it. -ASG */
371 if (event->param.conn.private_data_len < sizeof (*dp)
372 || dp->dp_protocol_major == 0)
360 return RDS_PROTOCOL_3_0; 373 return RDS_PROTOCOL_3_0;
361 374
362 common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS; 375 common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS;
@@ -388,7 +401,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
388 int err, destroy = 1; 401 int err, destroy = 1;
389 402
390 /* Check whether the remote protocol version matches ours. */ 403 /* Check whether the remote protocol version matches ours. */
391 version = rds_ib_protocol_compatible(dp); 404 version = rds_ib_protocol_compatible(event);
392 if (!version) 405 if (!version)
393 goto out; 406 goto out;
394 407