RDMA/nes: Don't allow userspace QPs to use STag zero

STag zero is a special STag that allows consumers to access any bus
address without registering memory. The nes driver unfortunately
allows STag zero to be used even with QPs created by unprivileged
userspace consumers, which means that any process with direct verbs
access to the nes device can read and write any memory accessible to
the underlying PCI device (usually any memory in the system). Such
access is usually given for cluster software such as MPI to use, so
this is a local privilege escalation bug on most systems running this
driver.

The driver was using STag zero to receive the last streaming mode
data; to allow STag zero to be disabled for unprivileged QPs, the
driver now registers a special MR for this data.

Cc: <stable@kernel.org>
Signed-off-by: Faisal Latif <faisal.latif@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Faisal Latif and committed by Linus Torvalds c12e56ef 7ef0d737

+37 -5
+34 -5
drivers/infiniband/hw/nes/nes_cm.c
··· 2490 int ret = 0; 2491 struct nes_vnic *nesvnic; 2492 struct nes_device *nesdev; 2493 2494 nesvnic = to_nesvnic(nesqp->ibqp.device); 2495 if (!nesvnic) 2496 return -EINVAL; 2497 2498 nesdev = nesvnic->nesdev; 2499 2500 nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", 2501 atomic_read(&nesvnic->netdev->refcnt)); ··· 2509 } else { 2510 /* Need to free the Last Streaming Mode Message */ 2511 if (nesqp->ietf_frame) { 2512 pci_free_consistent(nesdev->pcidev, 2513 nesqp->private_data_len+sizeof(struct ietf_mpa_frame), 2514 nesqp->ietf_frame, nesqp->ietf_frame_pbase); ··· 2547 u32 crc_value; 2548 int ret; 2549 int passive_state; 2550 2551 ibqp = nes_get_qp(cm_id->device, conn_param->qpn); 2552 if (!ibqp) ··· 2611 if (cm_id->remote_addr.sin_addr.s_addr != 2612 cm_id->local_addr.sin_addr.s_addr) { 2613 u64temp = (unsigned long)nesqp; 2614 u64temp |= NES_SW_CONTEXT_ALIGN>>1; 2615 set_wqe_64bit_value(wqe->wqe_words, 2616 NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, ··· 2641 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 2642 cpu_to_le32(conn_param->private_data_len + 2643 sizeof(struct ietf_mpa_frame)); 2644 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 2645 - cpu_to_le32((u32)nesqp->ietf_frame_pbase); 2646 - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 2647 - cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); 2648 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 2649 cpu_to_le32(conn_param->private_data_len + 2650 sizeof(struct ietf_mpa_frame)); 2651 - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 2652 2653 nesqp->nesqp_context->ird_ord_sizes |= 2654 cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
··· 2490 int ret = 0; 2491 struct nes_vnic *nesvnic; 2492 struct nes_device *nesdev; 2493 + struct nes_ib_device *nesibdev; 2494 2495 nesvnic = to_nesvnic(nesqp->ibqp.device); 2496 if (!nesvnic) 2497 return -EINVAL; 2498 2499 nesdev = nesvnic->nesdev; 2500 + nesibdev = nesvnic->nesibdev; 2501 2502 nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", 2503 atomic_read(&nesvnic->netdev->refcnt)); ··· 2507 } else { 2508 /* Need to free the Last Streaming Mode Message */ 2509 if (nesqp->ietf_frame) { 2510 + if (nesqp->lsmm_mr) 2511 + nesibdev->ibdev.dereg_mr(nesqp->lsmm_mr); 2512 pci_free_consistent(nesdev->pcidev, 2513 nesqp->private_data_len+sizeof(struct ietf_mpa_frame), 2514 nesqp->ietf_frame, nesqp->ietf_frame_pbase); ··· 2543 u32 crc_value; 2544 int ret; 2545 int passive_state; 2546 + struct nes_ib_device *nesibdev; 2547 + struct ib_mr *ibmr = NULL; 2548 + struct ib_phys_buf ibphysbuf; 2549 + struct nes_pd *nespd; 2550 + 2551 + 2552 2553 ibqp = nes_get_qp(cm_id->device, conn_param->qpn); 2554 if (!ibqp) ··· 2601 if (cm_id->remote_addr.sin_addr.s_addr != 2602 cm_id->local_addr.sin_addr.s_addr) { 2603 u64temp = (unsigned long)nesqp; 2604 + nesibdev = nesvnic->nesibdev; 2605 + nespd = nesqp->nespd; 2606 + ibphysbuf.addr = nesqp->ietf_frame_pbase; 2607 + ibphysbuf.size = conn_param->private_data_len + 2608 + sizeof(struct ietf_mpa_frame); 2609 + ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, 2610 + &ibphysbuf, 1, 2611 + IB_ACCESS_LOCAL_WRITE, 2612 + (u64 *)&nesqp->ietf_frame); 2613 + if (!ibmr) { 2614 + nes_debug(NES_DBG_CM, "Unable to register memory region" 2615 + "for lSMM for cm_node = %p \n", 2616 + cm_node); 2617 + return -ENOMEM; 2618 + } 2619 + 2620 + ibmr->pd = &nespd->ibpd; 2621 + ibmr->device = nespd->ibpd.device; 2622 + nesqp->lsmm_mr = ibmr; 2623 + 2624 u64temp |= NES_SW_CONTEXT_ALIGN>>1; 2625 set_wqe_64bit_value(wqe->wqe_words, 2626 NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, ··· 2611 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 2612 cpu_to_le32(conn_param->private_data_len + 2613 sizeof(struct ietf_mpa_frame)); 2614 + set_wqe_64bit_value(wqe->wqe_words, 2615 + NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, 2616 + (u64)nesqp->ietf_frame); 2617 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 2618 cpu_to_le32(conn_param->private_data_len + 2619 sizeof(struct ietf_mpa_frame)); 2620 + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; 2621 2622 nesqp->nesqp_context->ird_ord_sizes |= 2623 cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
+2
drivers/infiniband/hw/nes/nes_verbs.c
··· 1360 NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT); 1361 nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size << 1362 NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT); 1363 nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN); 1364 nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN); 1365 nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number + 1366 ((u32)nesqp->nesrcq->hw_cq.cq_number << 16)); 1367 u64temp = (u64)nesqp->hwqp.sq_pbase;
··· 1360 NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT); 1361 nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size << 1362 NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT); 1363 + if (!udata) { 1364 nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN); 1365 nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN); 1366 + } 1367 nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number + 1368 ((u32)nesqp->nesrcq->hw_cq.cq_number << 16)); 1369 u64temp = (u64)nesqp->hwqp.sq_pbase;
+1
drivers/infiniband/hw/nes/nes_verbs.h
··· 134 struct ietf_mpa_frame *ietf_frame; 135 dma_addr_t ietf_frame_pbase; 136 wait_queue_head_t state_waitq; 137 unsigned long socket; 138 struct nes_hw_qp hwqp; 139 struct work_struct work;
··· 134 struct ietf_mpa_frame *ietf_frame; 135 dma_addr_t ietf_frame_pbase; 136 wait_queue_head_t state_waitq; 137 + struct ib_mr *lsmm_mr; 138 unsigned long socket; 139 struct nes_hw_qp hwqp; 140 struct work_struct work;