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 | |
| 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>
| -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, |
