From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24FAFC77B7C for ; Wed, 10 May 2023 08:55:53 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CD84E6B0071; Wed, 10 May 2023 04:55:51 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C878B6B0078; Wed, 10 May 2023 04:55:51 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 92CFF6B0071; Wed, 10 May 2023 04:55:51 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 733916B0071 for ; Wed, 10 May 2023 04:55:51 -0400 (EDT) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 40D9D160771 for ; Wed, 10 May 2023 08:55:51 +0000 (UTC) X-FDA: 80773737702.15.236E44B Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net (zg8tmtyylji0my4xnjqumte4.icoremail.net [162.243.164.118]) by imf05.hostedemail.com (Postfix) with ESMTP id 8102810000D for ; Wed, 10 May 2023 08:55:47 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=pass header.d=pku.edu.cn header.s=dkim header.b=jvCCbw1W; spf=pass (imf05.hostedemail.com: domain of lrh2000@pku.edu.cn designates 162.243.164.118 as permitted sender) smtp.mailfrom=lrh2000@pku.edu.cn; dmarc=pass (policy=none) header.from=pku.edu.cn ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1683708949; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=FCdoZypKOCF7Yar38FzSX/85JDvNvpncqZ++kam1a4o=; b=etKni+AjM1zgJTo5KZh4WKuSmghGRIknQr2QR0rLLuR9tycnJr4vyuVDfo1c1koryFcn81 yaQqz0/rOE00edOIyEAle8OlafPF6L8ZsvSo2+KaLpwkfqbu+Hagn7TdiykYbh2lHQ0SdN 0kjp9lFGuK80kh3oiN+2kevCQuG08W8= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1683708949; a=rsa-sha256; cv=none; b=sK506RXo9MnpjPBMINLu8j+YOxhMXxGnicOXAUZvGHD6Itv2QEYTEKtBqvKx231JcxdDLA Vtfm3ff39nNlBoTxDY3C6ZSUsUeBMgOeSpYj/I+8b5GePgzIW5yG9nbap8QnjwiQGFZMSV rjBUVxmcS8rJ4Nm5GaU3M8vF9KhLd78= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=pass header.d=pku.edu.cn header.s=dkim header.b=jvCCbw1W; spf=pass (imf05.hostedemail.com: domain of lrh2000@pku.edu.cn designates 162.243.164.118 as permitted sender) smtp.mailfrom=lrh2000@pku.edu.cn; dmarc=pass (policy=none) header.from=pku.edu.cn DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=FCdoZypKOCF7Yar38FzSX/85JDvNvpncqZ ++kam1a4o=; b=jvCCbw1WH+LNsraRFmaFWBu79Plkic4etlcBNT2Q9/Pu+Ozgbj 5yIQu+HzX+Df+l7RnwSSM/X2QK4J727QlDceCkFh0FJZTq57YTKR1/5mVne2XE0l REqck6axoRwbXR0l1nvzX5Hin4BdXaYw97JAI5ZYCwuvCumiC2g04qrys= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBnb2cIXFtkW9d5Ag--.63159S3; Wed, 10 May 2023 16:55:42 +0800 (CST) From: Ruihan Li To: linux-mm@kvack.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Pasha Tatashin , David Hildenbrand , Matthew Wilcox , Andrew Morton , Christoph Hellwig , Greg Kroah-Hartman , Ruihan Li , syzbot+fcf1a817ceb50935ce99@syzkaller.appspotmail.comm, stable@vger.kernel.org Subject: [PATCH 1/4] usb: usbfs: Enforce page requirements for mmap Date: Wed, 10 May 2023 16:55:24 +0800 Message-Id: <20230510085527.57953-2-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230510085527.57953-1-lrh2000@pku.edu.cn> References: <20230510085527.57953-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:5oFpogBnb2cIXFtkW9d5Ag--.63159S3 X-Coremail-Antispam: 1UD129KBjvJXoWxXry7Gr1fXw4xWw13tF13urg_yoWrKF4kpF sxWr15CrW5tryxXrnxKFs8Za4Yvws5uFyUKrWxu3s3uF13J3sI9Fn5AFy5ZF1rJr4vgr1f tFn0krWYk3WUG37anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBF1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW0oVCq3wA2z4x0Y4vEx4A2 jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAac4AC62xK8xCEY4 vEwIxC4wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv 7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r 1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02 628vn2kIc2xKxwCY02Avz4vE-syl42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxFaVAv8V WkJr1UJwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUQZ23UUUUU= X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgEEBVPy770DbwAWsL X-Rspamd-Queue-Id: 8102810000D X-Rspam-User: X-Rspamd-Server: rspam06 X-Stat-Signature: 11uaqoxhoxssb4sz7g1dqzo9as6wfgf3 X-HE-Tag: 1683708947-307839 X-HE-Meta: U2FsdGVkX18nHclYMJOcrL7PUL7wYpLKlu3yxvTSbmqo+Ga4yrl0doaJ/fGQdU1YeFQ57KjSEWor5h+WgH8ya7D7ZcwnCsHqMiSgaNv5zkRGqnrgIF9RcDree6ZeqSx+YMqSO4rRTSLX4Qysvvz1q6C4MdGPsjqp7jV73oxD+BhGPYRr7Cm6lp+NtD5TX8tp9zFjLTiPhsuFaJ70gIuejgBAzgcrfjLCa/hdSK9mvw6N8SodBsrNvG6eNjrKGOmALQVJY787KKLFucjmrQpfoLwUryH21983Wi3S6vCqrN0ODUIbRrZ2GCpXcqshGQkYE4P/nDVto1Pdrx/NRZZzZOO/qO8pqSssmtPK6janF/qIlYVIMpYsnmHuJODjIsJyOPZvmDrIoDHPcNhj6295kGHbeI7EsuqhimQod1UGc+qVEyCZfR8ZQdek1NZ7w3zxnvOQlvydt6dE3zqjT+qcdDspKK0vqdWfvfEq4nQ2PBYVm+JQPauibWU3GsZNTWGsjJLmbPdg3ZVapRbrZ9MxiG6RACyyG/xKMnYt+8E8e8vuj/mDg0j6fScaBV+6sX44ndN23eiN9/1fMWZO2eduRTFSt3pGowoFVCH9EmM0P90dsCJwh/A1Vx03496HtNcn6nee/PQQkMkOKTaIuCws3k2m3LRNLMoADyVty9h49rkH+Z0UNwbi50jWI2PUcubJam28JHIUrhjMdqXGRHKElIOva+goytQu+Ew1p6ApqM7BE5y2Wa4IlHXNug5XoiA8S5K4/geIETS2pQtBvwWucxVt6FEZe/HQq866cyXTHCUP0qsJRz6R1UwuctEg58dsS2xvG0l/ChFGACB9cOBaY6D0fyPXf53f4wuDiwERem1J7ubKWQO/zeQUwfjikK+33mhKFoqaHMfUCzcW+H0dcAvwbz9m60JLI2I/lrhfjF/478HAC6oRVRyB66iVRMV8Z+F3kS9JDc+rWyaItoq IHWmT+hP hWwblXg7MN2HFmbGifSu0WU+6vtrzMPEcK2Cx5MBunKxojmr0CMYpY8IokUUiGn6udMdmNEGrkwaML0lpR3DwDrcVjKIvCMnnVbbXy/CCqVCbN4StHzMgT6c9UWQh6TljDFFJWqKgYkZEdBQiitaRMulVAPWq2IfLFShwvrNk+gViz4YAzYU6Xm/N5YMQjQugI/0Q2V063JSg3YuwibZLhoJHxhwh1rrXFKztScNiRM4K6OxmIgzrsTidDTJmHKWCJKw2UlX5drvcELypFc03F8LJM1dFoi79OPOeBzih2VbqEN6iARz0k+c46A== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The current implementation of usbdev_mmap uses usb_alloc_coherent to allocate memory pages that will later be mapped into the user space. Meanwhile, usb_alloc_coherent employs three different methods to allocate memory, as outlined below: * If hcd->localmem_pool is non-null, it uses gen_pool_dma_alloc to allocate memory. * If DMA is not available, it uses kmalloc to allocate memory. * Otherwise, it uses dma_alloc_coherent. However, it should be noted that gen_pool_dma_alloc does not guarantee that the resulting memory will be page-aligned. Furthermore, trying to map slab pages (i.e., memory allocated by kmalloc) into the user space is not resonable and can lead to problems, such as a type confusion bug when PAGE_TABLE_CHECK=y [1]. To address these issues, this patch introduces hcd_alloc_coherent_pages, which addresses the above two problems. Specifically, hcd_alloc_coherent_pages uses gen_pool_dma_alloc_align instead of gen_pool_dma_alloc to ensure that the memory is page-aligned. To replace kmalloc, hcd_alloc_coherent_pages directly allocates pages by calling __get_free_pages. Reported-by: syzbot+fcf1a817ceb50935ce99@syzkaller.appspotmail.comm Closes: https://lore.kernel.org/lkml/000000000000258e5e05fae79fc1@google.com/ [1] Cc: stable@vger.kernel.org Signed-off-by: Ruihan Li --- drivers/usb/core/buffer.c | 41 +++++++++++++++++++++++++++++++++++++++ drivers/usb/core/devio.c | 9 +++++---- include/linux/usb/hcd.h | 5 +++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index fbb087b72..6010ef9f5 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -172,3 +172,44 @@ void hcd_buffer_free( } dma_free_coherent(hcd->self.sysdev, size, addr, dma); } + +void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, size_t size, + gfp_t mem_flags, dma_addr_t *dma) +{ + if (size == 0) + return NULL; + + if (hcd->localmem_pool) + return gen_pool_dma_alloc_align(hcd->localmem_pool, + size, dma, PAGE_SIZE); + + /* some USB hosts just use PIO */ + if (!hcd_uses_dma(hcd)) { + *dma = DMA_MAPPING_ERROR; + return (void *)__get_free_pages(mem_flags, + get_order(size)); + } + + return dma_alloc_coherent(hcd->self.sysdev, + size, dma, mem_flags); +} + +void hcd_buffer_free_pages(struct usb_hcd *hcd, size_t size, + void *addr, dma_addr_t dma) +{ + if (!addr) + return; + + if (hcd->localmem_pool) { + gen_pool_free(hcd->localmem_pool, + (unsigned long)addr, size); + return; + } + + if (!hcd_uses_dma(hcd)) { + free_pages((unsigned long)addr, get_order(size)); + return; + } + + dma_free_coherent(hcd->self.sysdev, size, addr, dma); +} diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e501a03d6..b4cf9e860 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -186,6 +186,7 @@ static int connected(struct usb_dev_state *ps) static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count) { struct usb_dev_state *ps = usbm->ps; + struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); unsigned long flags; spin_lock_irqsave(&ps->lock, flags); @@ -194,8 +195,8 @@ static void dec_usb_memory_use_count(struct usb_memory *usbm, int *count) list_del(&usbm->memlist); spin_unlock_irqrestore(&ps->lock, flags); - usb_free_coherent(ps->dev, usbm->size, usbm->mem, - usbm->dma_handle); + hcd_buffer_free_pages(hcd, usbm->size, usbm->mem, + usbm->dma_handle); usbfs_decrease_memory_usage( usbm->size + sizeof(struct usb_memory)); kfree(usbm); @@ -247,8 +248,8 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) goto error_decrease_mem; } - mem = usb_alloc_coherent(ps->dev, size, GFP_USER | __GFP_NOWARN, - &dma_handle); + mem = hcd_buffer_alloc_pages(hcd, size, GFP_USER | __GFP_NOWARN, + &dma_handle); if (!mem) { ret = -ENOMEM; goto error_free_usbm; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 094c77eaf..79f89109e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -501,6 +501,11 @@ void *hcd_buffer_alloc(struct usb_bus *bus, size_t size, void hcd_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); +void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, size_t size, + gfp_t mem_flags, dma_addr_t *dma); +void hcd_buffer_free_pages(struct usb_hcd *hcd, size_t size, + void *addr, dma_addr_t dma); + /* generic bus glue, needed for host controllers that don't use PCI */ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); -- 2.40.1