From patchwork Wed Nov 10 10:03:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 313482 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAAA2lOQ024291 for ; Wed, 10 Nov 2010 10:03:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755301Ab0KJKDm (ORCPT ); Wed, 10 Nov 2010 05:03:42 -0500 Received: from dgate10.ts.fujitsu.com ([80.70.172.49]:59030 "EHLO dgate10.ts.fujitsu.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755280Ab0KJKDl (ORCPT ); Wed, 10 Nov 2010 05:03:41 -0500 DomainKey-Signature: s=s1536a; d=ts.fujitsu.com; c=nofws; q=dns; h=X-SBRSScore:X-IronPort-AV:Received:X-IronPort-AV: Received:Received:From:To:Cc:Subject:Date:Message-Id: X-Mailer:In-Reply-To:References; b=rla5w1UWZ9xWyRl0VkfOrRblD50r4G6t2dLEkS6r1KNZgyyPrVmb5kGB 9PS3JQLoWANFhxeGsVne06TqaMJwJOF9oh5pv9v8+SwflwvMKWaZ4VwOR L0aSXO5fwbjUNHPDZWZEDnsczKudjVYa4Fk0etw+71sNc5FM1ni7NEN4G MUs68cZOeDnWo2M5dvNNftFBLe6cgAKplALkvS+3aynbQ704PKUFZ/Mz5 i/FF3ANurzWZfYnpOZv1R2E9IopL+; DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=ts.fujitsu.com; i=martin.wilck@ts.fujitsu.com; q=dns/txt; s=s1536b; t=1289383420; x=1320919420; h=from:to:cc:subject:date:message-id:in-reply-to: references; z=From:=20Martin=20Wilck=20 |To:=20jbarnes@virtuousgeek.org|Cc:=20gerhard.wichert@ts. fujitsu.com,=20linux-kernel@vger.kernel.org,=20linux-pci@ vger.kernel.org,=20Martin=20Wilck=20|Subject:=20[PATCH]=20fix=20size=20checks=20for =20mmap()=20on=20/proc/bus/pci=20files=20(updated)|Date: =20Wed,=2010=20Nov=202010=2011:03:21=20+0100|Message-Id: =20<1289383401-1357-1-git-send-email-martin.wilck@ts.fuji tsu.com>|In-Reply-To:=20<20101109084206.1b6ac66a@jbarnes- desktop>|References:=20<20101109084206.1b6ac66a@jbarnes-d esktop>; bh=+CZTEt3X3GQdDXVw+ZXtt3jJYr2+mA8CkiUScntrz+0=; b=h+oiKDgAoXMXKas1HDyixN8k63SVAFUdT4qBy2qCWAzojs8PUNEDEAvH drpFgR0zEIBjpL8uWFGgrpLI+XDsONRVZV4THF0hWYRFbe3qDaTgMa6rn qqEuFzXKaFbcCBmDdt9x5hh3cAV3rPcYPkZmVpi/hQpEq0rZrMlBu8hcI oKy4/KgAsUcy9aCUpVTBuXoqsYW/qjESgaOU9hI+omMIYhQknQj0duHie Rl5DL+JYzYoWrN/7Nt63Ntu+ZlNQV; X-SBRSScore: None X-IronPort-AV: E=Sophos;i="4.59,177,1288566000"; d="scan'208";a="58554224" Received: from abgdgate30u.abg.fsc.net ([172.25.138.66]) by dgate10u.abg.fsc.net with ESMTP; 10 Nov 2010 11:03:38 +0100 X-IronPort-AV: E=Sophos;i="4.59,177,1288566000"; d="scan'208";a="102636357" Received: from unknown (HELO pldp.psw.pdbps.fsc.net) ([172.25.253.61]) by abgdgate30u.abg.fsc.net with ESMTP; 10 Nov 2010 11:03:37 +0100 Received: by pldp.psw.pdbps.fsc.net (Postfix, from userid 1001) id 68E6F57101; Wed, 10 Nov 2010 11:03:37 +0100 (CET) From: Martin Wilck To: jbarnes@virtuousgeek.org Cc: gerhard.wichert@ts.fujitsu.com, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Martin Wilck Subject: [PATCH] fix size checks for mmap() on /proc/bus/pci files (updated) Date: Wed, 10 Nov 2010 11:03:21 +0100 Message-Id: <1289383401-1357-1-git-send-email-martin.wilck@ts.fujitsu.com> X-Mailer: git-send-email 1.6.3.2 In-Reply-To: <20101109084206.1b6ac66a@jbarnes-desktop> References: <20101109084206.1b6ac66a@jbarnes-desktop> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 10 Nov 2010 10:03:43 +0000 (UTC) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index b5a7d9b..25accc9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -705,17 +705,21 @@ void pci_remove_legacy_files(struct pci_bus *b) #ifdef HAVE_PCI_MMAP -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) +int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, + enum pci_mmap_api mmap_api) { - unsigned long nr, start, size; + unsigned long nr, start, size, pci_start; + if (pci_resource_len(pdev, resno) == 0) + return 0; nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; - if (start < size && size - start >= nr) + pci_start = (mmap_api == PCI_MMAP_SYSFS) ? + pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; + if (start >= pci_start && start < pci_start + size && + start + nr <= pci_start + size) return 1; - WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", - current->comm, start, start+nr, pci_name(pdev), resno, size); return 0; } @@ -745,8 +749,14 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; - if (!pci_mmap_fits(pdev, i, vma)) + if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { + WARN(1, "process \"%s\" tried to map 0x%08lx bytes " + "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", + current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, + pci_name(pdev), i, + pci_resource_start(pdev, i), pci_resource_len(pdev, i)); return -EINVAL; + } /* pci_mmap_page_range() expects the same kind of entry as coming * from /proc/bus/pci/ which is a "user visible" value. If this is diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index f5c7c38..7d33f66 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -22,8 +22,13 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev); #endif extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP +enum pci_mmap_api { + PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ + PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ +}; extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vma); + struct vm_area_struct *vmai, + enum pci_mmap_api mmap_api); #endif int pci_probe_reset_function(struct pci_dev *dev); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 297b72c..ea00647 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -257,7 +257,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) /* Make sure the caller is mapping a real resource for this device */ for (i = 0; i < PCI_ROM_RESOURCE; i++) { - if (pci_mmap_fits(dev, i, vma)) + if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) break; }