Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp5051363pxu; Thu, 10 Dec 2020 11:38:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJymsSn/BKCcR2LIcA21Ou+P/ChiMG7wht7fV6dNlZiKDEi9Zt064TAUV1QXL5ymYm+yuN9p X-Received: by 2002:a17:906:d10f:: with SMTP id b15mr7691410ejz.268.1607629119342; Thu, 10 Dec 2020 11:38:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607629119; cv=none; d=google.com; s=arc-20160816; b=E2mk+tG4d3NjhtlQp5AsBX+FZGHcSF0Gzsek4bW16KfwWYxIrBPE81zab5pUZJ3gCt +pRO57xdrZ3/7ggYEWnyY2MuKZB1SS1e/6kuMUlzW9zHAGFzmbobSogIWv2MALogXpqw xMMCbTkwXzWwyW26n3qdXNF1De3avlxBXMCy5cF9HeqyRL12tqBC1iP+/LoatKO3FQdE +kEnQ3rTHqa+ZzKjLOzUDbmR6wRAv1fupKZ4MxHkPEmtiFw6mwFUxmHfzYvlQcgRepkW i0+Otywc7e7RYfjTK7FKYnh9OQdabrskUJVcwYflU4p1UwK/knPJXnfO5b6P4hckJ1zj z6/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=qZOOUrw3tC1ZgJn0M/yATFIvmqNAIPJY1cMZGm03z1o=; b=Ii6+vQASsAkuVs+fZDgOAJUW0evBRXCH6GAcc1gkp/EpyDl+Bqhi83OY+cMMPn5a5g nNkp7etFWUCowb8R2QEyk2X7F4oQixEdIAydUmlC2qP8y7MVW7cdlgs9D33EGDxSf7kd 7k9lyq9jcT4qU98TfdHsCLTi6V8WT77dnBlLoIV0tXBprdQeQ8RryM723lVaeUeAn/rg MpHZmWIVn4EtNM91ZLVhh7sDWBJP3INR7q9BupuR7nSVFYdBGQBi0YWSL40Ww0TFnGj3 19r7lbGTvgrtxgm28dMYsc5w/q8eLe+dALKn1l80nAsGfTr0Mcvk/QQdlIh1ZFU0wQve R7qA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id aq15si3037998ejc.523.2020.12.10.11.38.12; Thu, 10 Dec 2020 11:38:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393421AbgLJTeO (ORCPT + 99 others); Thu, 10 Dec 2020 14:34:14 -0500 Received: from mail.kernel.org ([198.145.29.99]:37504 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726263AbgLJO3b (ORCPT ); Thu, 10 Dec 2020 09:29:31 -0500 From: Greg Kroah-Hartman Authentication-Results: mail.kernel.org; dkim=permerror (bad message/signature format) To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, stable@kernel.org, Di Zhu , Shiraz Saleem , Jason Gunthorpe Subject: [PATCH 4.9 16/45] RDMA/i40iw: Address an mmap handler exploit in i40iw Date: Thu, 10 Dec 2020 15:26:30 +0100 Message-Id: <20201210142603.165233619@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201210142602.361598591@linuxfoundation.org> References: <20201210142602.361598591@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Shiraz Saleem commit 2ed381439e89fa6d1a0839ef45ccd45d99d8e915 upstream. i40iw_mmap manipulates the vma->vm_pgoff to differentiate a push page mmap vs a doorbell mmap, and uses it to compute the pfn in remap_pfn_range without any validation. This is vulnerable to an mmap exploit as described in: https://lore.kernel.org/r/20201119093523.7588-1-zhudi21@huawei.com The push feature is disabled in the driver currently and therefore no push mmaps are issued from user-space. The feature does not work as expected in the x722 product. Remove the push module parameter and all VMA attribute manipulations for this feature in i40iw_mmap. Update i40iw_mmap to only allow DB user mmapings at offset = 0. Check vm_pgoff for zero and if the mmaps are bound to a single page. Cc: Fixes: d37498417947 ("i40iw: add files for iwarp interface") Link: https://lore.kernel.org/r/20201125005616.1800-2-shiraz.saleem@intel.com Reported-by: Di Zhu Signed-off-by: Shiraz Saleem Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/i40iw/i40iw_main.c | 5 ---- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 36 +++++------------------------- 2 files changed, 7 insertions(+), 34 deletions(-) --- a/drivers/infiniband/hw/i40iw/i40iw_main.c +++ b/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -54,10 +54,6 @@ #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD) -static int push_mode; -module_param(push_mode, int, 0644); -MODULE_PARM_DESC(push_mode, "Low latency mode: 0=disabled (default), 1=enabled)"); - static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all"); @@ -1524,7 +1520,6 @@ static enum i40iw_status_code i40iw_setu if (status) goto exit; iwdev->obj_next = iwdev->obj_mem; - iwdev->push_mode = push_mode; init_waitqueue_head(&iwdev->vchnl_waitq); init_waitqueue_head(&dev->vf_reqs); --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -208,38 +208,16 @@ static int i40iw_dealloc_ucontext(struct */ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) { - struct i40iw_ucontext *ucontext; - u64 db_addr_offset; - u64 push_offset; + struct i40iw_ucontext *ucontext = to_ucontext(context); + u64 dbaddr; - ucontext = to_ucontext(context); - if (ucontext->iwdev->sc_dev.is_pf) { - db_addr_offset = I40IW_DB_ADDR_OFFSET; - push_offset = I40IW_PUSH_OFFSET; - if (vma->vm_pgoff) - vma->vm_pgoff += I40IW_PF_FIRST_PUSH_PAGE_INDEX - 1; - } else { - db_addr_offset = I40IW_VF_DB_ADDR_OFFSET; - push_offset = I40IW_VF_PUSH_OFFSET; - if (vma->vm_pgoff) - vma->vm_pgoff += I40IW_VF_FIRST_PUSH_PAGE_INDEX - 1; - } + if (vma->vm_pgoff || vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; - vma->vm_pgoff += db_addr_offset >> PAGE_SHIFT; + dbaddr = I40IW_DB_ADDR_OFFSET + pci_resource_start(ucontext->iwdev->ldev->pcidev, 0); - if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - vma->vm_private_data = ucontext; - } else { - if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - else - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - } - - if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT), - PAGE_SIZE, vma->vm_page_prot)) + if (io_remap_pfn_range(vma, vma->vm_start, dbaddr >> PAGE_SHIFT, PAGE_SIZE, + pgprot_noncached(vma->vm_page_prot))) return -EAGAIN; return 0;