From patchwork Fri Sep 16 20:01:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 671095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3sbR8R1jdbz9s2G for ; Sat, 17 Sep 2016 06:04:55 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965268AbcIPUCh (ORCPT ); Fri, 16 Sep 2016 16:02:37 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:23791 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964829AbcIPUCf (ORCPT ); Fri, 16 Sep 2016 16:02:35 -0400 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u8GK2S9d022033 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 16 Sep 2016 20:02:29 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u8GK2Sf8010495 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 16 Sep 2016 20:02:28 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u8GK2SBp020108; Fri, 16 Sep 2016 20:02:28 GMT Received: from aserv0021.oracle.com (/10.132.126.127) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 16 Sep 2016 13:02:28 -0700 From: Yinghai Lu To: Bjorn Helgaas , David Miller , Benjamin Herrenschmidt Cc: Wei Yang , Khalid Aziz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH v14 04/17] PCI: Check resource alignment for /sys pci_mmap_resource path Date: Fri, 16 Sep 2016 13:01:54 -0700 Message-Id: <20160916200207.21439-5-yinghai@kernel.org> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160916200207.21439-1-yinghai@kernel.org> References: <20160916200207.21439-1-yinghai@kernel.org> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org When user access /sys/.../resourceX with pci_mmap_resource(), pci_mmap_resource(): ... pci_resource_to_user(pdev, i, res, &start, &end); vma->vm_pgoff += start >> PAGE_SHIFT; mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); so it will return virtual address for round_down of start. user code should pass offset with PAGE_SIZE offset. fd = open(argv[1], O_RDONLY); ... sscanf(argv[2], "0x%lx", &offset); left = offset & (PAGE_SIZE - 1); offset &= PAGE_MASK; addr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, offset); for (i = 0; i < 8; i++) printf("%x ", addr[i + left]); munmap(addr, PAGE_SIZE); close(fd); When the resource start is not PAGE_SIZE aligned, it should be io port, pci_mmap_resource could return round_down address of resource start. As the whole point for pci_mmap_resource is passing offset in [0, resource_size), user may assume virtual add is corresponding to unaligned resource_size. Later they could get wrong value with offset to resource start. Block the path for now, and need to use pci_read_resource_io /pci_write_resource_io path instead. user code should be like: fd = open(argv[1], O_RDONLY); ... sscanf(argv[2], "0x%lx", &offset); for (i = 0; i < 8; i++) { pread(fd, &buf, 1, i + offset); } close(fd); Signed-off-by: Yinghai Lu --- drivers/pci/pci-sysfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d55d93d..e2eb79f 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1023,6 +1023,16 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; + /* + * resource start have to be PAGE_SIZE aligned, as we pass + * back virt address include round down of resource_start, + * that caller can not figure out directly. + * when it is not aligned, that mean it is io port, should go + * pci_read_resource_io()/pci_write_resource_io() path. + */ + if (res->start & ~PAGE_MASK) + return -EINVAL; + if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) return -EINVAL;