• Mike Marciniszyn's avatar
    RDMA/core: Ensure security pkey modify is not lost · 2d47fbac
    Mike Marciniszyn authored
    The following modify sequence (loosely based on ipoib) will lose a pkey
    modifcation:
    
    - Modify (pkey index, port)
    - Modify (new pkey index, NO port)
    
    After the first modify, the qp_pps list will have saved the pkey and the
    unit on the main list.
    
    During the second modify, get_new_pps() will fetch the port from qp_pps
    and read the new pkey index from qp_attr->pkey_index.  The state will
    still be zero, or IB_PORT_PKEY_NOT_VALID. Because of the invalid state,
    the new values will never replace the one in the qp pps list, losing the
    new pkey.
    
    This happens because the following if statements will never correct the
    state because the first term will be false. If the code had been executed,
    it would incorrectly overwrite valid values.
    
      if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT))
    	  new_pps->main.state = IB_PORT_PKEY_VALID;
    
      if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) {
    	  new_pps->main.port_num = qp_pps->main.port_num;
    	  new_pps->main.pkey_index = qp_pps->main.pkey_index;
    	  if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)
    		  new_pps->main.state = IB_PORT_PKEY_VALID;
      }
    
    Fix by joining the two if statements with an or test to see if qp_pps is
    non-NULL and in the correct state.
    
    Fixes: 1dd01788 ("RDMA/core: Fix protection fault in get_pkey_idx_qp_list")
    Link: https://lore.kernel.org/r/20200313124704.14982.55907.stgit@awfm-01.aw.intel.comReviewed-by: default avatarKaike Wan <kaike.wan@intel.com>
    Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
    Reviewed-by: default avatarLeon Romanovsky <leonro@mellanox.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
    2d47fbac
security.c 18.1 KB