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