Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp645387ybz; Wed, 22 Apr 2020 05:24:13 -0700 (PDT) X-Google-Smtp-Source: APiQypKhDEFD7Oiyfsf27bwhaPk78sDpygXAl1DRmhbS0EMJY9zy0RxUQUVmhqBQC3dQR7APAb1c X-Received: by 2002:a17:906:9443:: with SMTP id z3mr26110181ejx.114.1587558252976; Wed, 22 Apr 2020 05:24:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587558252; cv=none; d=google.com; s=arc-20160816; b=slih0+kK0MVE7aDSavXuFhZaWA1jq76Zf/VFvWmjKwmMDt6O3zCOHxLajU29KyMlXW kTI/Q5lzUl6cNAhbl2x99dJoFM2sOhXvezBgnYVY6dvXTyLsvJo3ql2MzjjVQyXZVQW3 +g73D9UJX0NVipdcuiN9JGe17P0P0CGHaGmMw3Q7pSGUamamVpB1BgMLNJG2J7bEDNxA DH2qM4KKX8zRxHM0n/covwXS/F5/KSS+BtypYFT73MUbyjWEPbicmz/8lu1TJApxCuT8 Qox+eeBj3DdRpA4TzgQ+AH0CFZMzNPoXN/zay5qa68VA6ri8G+z256/Ojui+RoatklYt H9ig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=dq2Aa5bVxI/FDqIygTzDJ11bZksrU5e9yrEhbsUhrOw=; b=Uf1RuKiJuc7r2vWKPcVH48RaGvSAL/ZM+vn7RKZmmkT1n9wZx9vBL98SUeIIJRrqto Gt2TDGzQrwp+fPhwtni4xnn+aWoUGr4gTmcNS41MgHk4rMAu49FZi33F4R3CO7SI7u03 IBvt9qDQs+sZRn8I0fQD2YSrih3JCr8EW2C8HYuhhZg1ASWU7x+QNMA9MDvrWHTNKn19 jU7I/bEJXl/U7oE5rc6vGXJInnptBRd23mDxoSTNZKVQl2Rt6dJVagJKFxWMLtFMxdud HbYpn+cHuwAw49XvrqlhAFezu2KxCaPlDModKVmQFy4vUmigvpGXfgBStgDdWDwale7p rctg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=exhyVC7C; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x61si3453306ede.604.2020.04.22.05.23.49; Wed, 22 Apr 2020 05:24:12 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b=exhyVC7C; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731189AbgDVKdY (ORCPT + 99 others); Wed, 22 Apr 2020 06:33:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:33256 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729736AbgDVKYt (ORCPT ); Wed, 22 Apr 2020 06:24:49 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A41FE2071E; Wed, 22 Apr 2020 10:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1587551089; bh=fa6sFC6ExgJLrtzdqYbGOIXx3ZLfMUmZOOEM2DJyOJ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=exhyVC7CPoTysCJE84517JputvHvV7SQu6JszM6LHhXbFgctUcFzNBRiLZ9z7/n7O beF5RS+NozFSpMZ7mJBPhmc0mLuNo+HdHlKqGmKUQ0hRYegE9WTbKWdceHgOTfoSRx qLNCoh0GUYp+wUEDI6rQ8ZGoBDlANWmkbiQt/tW4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Kevin Grandemange , Christoph Hellwig , Sasha Levin Subject: [PATCH 5.6 069/166] dma-coherent: fix integer overflow in the reserved-memory dma allocation Date: Wed, 22 Apr 2020 11:56:36 +0200 Message-Id: <20200422095056.319089776@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200422095047.669225321@linuxfoundation.org> References: <20200422095047.669225321@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kevin Grandemange [ Upstream commit 286c21de32b904131f8cf6a36ce40b8b0c9c5da3 ] pageno is an int and the PAGE_SHIFT shift is done on an int, overflowing if the memory is bigger than 2G This can be reproduced using for example a reserved-memory of 4G reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; reserved_dma: buffer@0 { compatible = "shared-dma-pool"; no-map; reg = <0x5 0x00000000 0x1 0x0>; }; }; Signed-off-by: Kevin Grandemange Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- kernel/dma/coherent.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c index 551b0eb7028a3..2a0c4985f38e4 100644 --- a/kernel/dma/coherent.c +++ b/kernel/dma/coherent.c @@ -134,7 +134,7 @@ static void *__dma_alloc_from_coherent(struct device *dev, spin_lock_irqsave(&mem->spinlock, flags); - if (unlikely(size > (mem->size << PAGE_SHIFT))) + if (unlikely(size > ((dma_addr_t)mem->size << PAGE_SHIFT))) goto err; pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); @@ -144,8 +144,9 @@ static void *__dma_alloc_from_coherent(struct device *dev, /* * Memory was found in the coherent area. */ - *dma_handle = dma_get_device_base(dev, mem) + (pageno << PAGE_SHIFT); - ret = mem->virt_base + (pageno << PAGE_SHIFT); + *dma_handle = dma_get_device_base(dev, mem) + + ((dma_addr_t)pageno << PAGE_SHIFT); + ret = mem->virt_base + ((dma_addr_t)pageno << PAGE_SHIFT); spin_unlock_irqrestore(&mem->spinlock, flags); memset(ret, 0, size); return ret; @@ -194,7 +195,7 @@ static int __dma_release_from_coherent(struct dma_coherent_mem *mem, int order, void *vaddr) { if (mem && vaddr >= mem->virt_base && vaddr < - (mem->virt_base + (mem->size << PAGE_SHIFT))) { + (mem->virt_base + ((dma_addr_t)mem->size << PAGE_SHIFT))) { int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; unsigned long flags; @@ -238,10 +239,10 @@ static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem, struct vm_area_struct *vma, void *vaddr, size_t size, int *ret) { if (mem && vaddr >= mem->virt_base && vaddr + size <= - (mem->virt_base + (mem->size << PAGE_SHIFT))) { + (mem->virt_base + ((dma_addr_t)mem->size << PAGE_SHIFT))) { unsigned long off = vma->vm_pgoff; int start = (vaddr - mem->virt_base) >> PAGE_SHIFT; - int user_count = vma_pages(vma); + unsigned long user_count = vma_pages(vma); int count = PAGE_ALIGN(size) >> PAGE_SHIFT; *ret = -ENXIO; -- 2.20.1