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>

authored by Michael S. Tsirkin and committed by Roland Dreier bf6d9e23 187a2586

+22 -19
+22 -19
drivers/infiniband/core/user_mad.c
··· 310 u8 method; 311 __be64 *tid; 312 int ret, length, hdr_len, copy_offset; 313 - int rmpp_active = 0; 314 315 if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) 316 return -EINVAL; ··· 360 } 361 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) { 364 - /* RMPP active */ 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; 382 } else { 383 hdr_len = IB_MGMT_MAD_HDR; 384 copy_offset = IB_MGMT_MAD_HDR; 385 } 386 387 packet->msg = ib_create_send_mad(agent,
··· 310 u8 method; 311 __be64 *tid; 312 int ret, length, hdr_len, copy_offset; 313 + int rmpp_active, has_rmpp_header; 314 315 if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) 316 return -EINVAL; ··· 360 } 361 362 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; 363 + if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { 364 + hdr_len = IB_MGMT_SA_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; 372 } else { 373 hdr_len = 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; 388 } 389 390 packet->msg = ib_create_send_mad(agent,