diff options
author | Michael S. Tsirkin <mst@mellanox.co.il> | 2005-11-28 16:07:20 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2005-11-28 16:07:20 -0500 |
commit | bf6d9e23a36c8a01bf6fbb945387d8ca3870ff71 (patch) | |
tree | 9fd732ebc6b85090b64862c4ee3af7078ba1f822 /drivers/infiniband | |
parent | 187a25863fe014486ee834164776b2a587d6934d (diff) |
IB/umad: fix RMPP handling
ib_umad_write in user_mad.c is looking at rmpp_hdr field in MAD before
checking that the MAD actually has the RMPP header. So for a MAD
without RMPP header it looks like we are actually checking a bit
inside M_Key, or something.
Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index e73f81c22381..eb7f52537ccc 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -310,7 +310,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
310 | u8 method; | 310 | u8 method; |
311 | __be64 *tid; | 311 | __be64 *tid; |
312 | int ret, length, hdr_len, copy_offset; | 312 | int ret, length, hdr_len, copy_offset; |
313 | int rmpp_active = 0; | 313 | int rmpp_active, has_rmpp_header; |
314 | 314 | ||
315 | if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) | 315 | if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) |
316 | return -EINVAL; | 316 | return -EINVAL; |
@@ -360,28 +360,31 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
360 | } | 360 | } |
361 | 361 | ||
362 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; | 362 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; |
363 | if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) { | 363 | if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { |
364 | /* RMPP active */ | 364 | hdr_len = IB_MGMT_SA_HDR; |
365 | if (!agent->rmpp_version) { | ||
366 | ret = -EINVAL; | ||
367 | goto err_ah; | ||
368 | } | ||
369 | |||
370 | /* Validate that the management class can support RMPP */ | ||
371 | if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { | ||
372 | hdr_len = IB_MGMT_SA_HDR; | ||
373 | } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
374 | (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) { | ||
375 | hdr_len = IB_MGMT_VENDOR_HDR; | ||
376 | } else { | ||
377 | ret = -EINVAL; | ||
378 | goto err_ah; | ||
379 | } | ||
380 | rmpp_active = 1; | ||
381 | copy_offset = IB_MGMT_RMPP_HDR; | 365 | copy_offset = IB_MGMT_RMPP_HDR; |
366 | has_rmpp_header = 1; | ||
367 | } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START && | ||
368 | rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) { | ||
369 | hdr_len = IB_MGMT_VENDOR_HDR; | ||
370 | copy_offset = IB_MGMT_RMPP_HDR; | ||
371 | has_rmpp_header = 1; | ||
382 | } else { | 372 | } else { |
383 | hdr_len = IB_MGMT_MAD_HDR; | 373 | hdr_len = IB_MGMT_MAD_HDR; |
384 | copy_offset = IB_MGMT_MAD_HDR; | 374 | copy_offset = IB_MGMT_MAD_HDR; |
375 | has_rmpp_header = 0; | ||
376 | } | ||
377 | |||
378 | if (has_rmpp_header) | ||
379 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | ||
380 | IB_MGMT_RMPP_FLAG_ACTIVE; | ||
381 | else | ||
382 | rmpp_active = 0; | ||
383 | |||
384 | /* Validate that the management class can support RMPP */ | ||
385 | if (rmpp_active && !agent->rmpp_version) { | ||
386 | ret = -EINVAL; | ||
387 | goto err_ah; | ||
385 | } | 388 | } |
386 | 389 | ||
387 | packet->msg = ib_create_send_mad(agent, | 390 | packet->msg = ib_create_send_mad(agent, |