From patchwork Sun Jun 9 13:50:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hauke Mehrtens X-Patchwork-Id: 1112640 X-Patchwork-Delegate: hauke@hauke-m.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.openwrt.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=hauke-m.de Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="GUZxkZ5H"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45MHjg1SBkz9s7h for ; Sun, 9 Jun 2019 23:51:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:Message-Id:Date:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=/ArI31/dGJtXLp2rlkW4IMxNmQxGylM8knKrdE7qtXs=; b=GUZxkZ5HND6STJ YBUFtZxQVfybNZLJs2rC6hOCwGbV04qf9e3X965knq5P1e7Htp84Cf/JNpwAEQr+O2FzzON9yUjok 5uhaFJR/kpIA+2DEIyL2NWSxUkLoN6ldit0zLK5J1MNWvKxLxD/DCTkfghbvZC8mMMyIDG+FOyiuI 4ukIrwRsInEHLTkv58NaJzGPe82COIjHwXM3xYdtn+pT6CbzXrRHqfzAOcv1uL/RW8MaAbEBGiBDt AWDvx638RLscHlMyXxhhxezViNfd3XLNYcZcDCUCdBYmXodqlF6/aKMNYadXtEby1JNgWifpw3Ncq 3dX/Qz9d7EhdoLtToPJQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hZyDj-0003hR-ME; Sun, 09 Jun 2019 13:50:51 +0000 Received: from mx2.mailbox.org ([80.241.60.215]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hZyDe-0003gz-Fc for openwrt-devel@lists.openwrt.org; Sun, 09 Jun 2019 13:50:49 +0000 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx2.mailbox.org (Postfix) with ESMTPS id 28A0CA0163; Sun, 9 Jun 2019 15:50:39 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter03.heinlein-hosting.de (spamfilter03.heinlein-hosting.de [80.241.56.117]) (amavisd-new, port 10030) with ESMTP id O7FxPFk5llXq; Sun, 9 Jun 2019 15:50:29 +0200 (CEST) From: Hauke Mehrtens To: openwrt-devel@lists.openwrt.org Date: Sun, 9 Jun 2019 15:50:20 +0200 Message-Id: <20190609135020.11156-1-hauke@hauke-m.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190609_065046_836964_8EBD5800 X-CRM114-Status: GOOD ( 18.15 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [80.241.60.215 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record Subject: [OpenWrt-Devel] [PATCH] kernel: backport MIPS: Bounds check virt_addr_valid X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Hauke Mehrtens Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org This fixes bugs in the copy_{to,from}_user hardening like this: usercopy: kernel memory exposure attempt detected from c0d173c1 (kmalloc-256) (71 bytes) Kernel bug detected[#1]: Fixes: 9b1239451d6 ("Kernel: Activate CONFIG_HARDENED_USERCOPY") Fixes: FS#2305 and FS#2297 Signed-off-by: Hauke Mehrtens --- ....2-MIPS-Bounds-check-virt_addr_valid.patch | 70 +++++++++++++++++++ ....2-MIPS-Bounds-check-virt_addr_valid.patch | 70 +++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 target/linux/generic/backport-4.14/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch create mode 100644 target/linux/generic/backport-4.19/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch diff --git a/target/linux/generic/backport-4.14/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch b/target/linux/generic/backport-4.14/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch new file mode 100644 index 0000000000..028e84a691 --- /dev/null +++ b/target/linux/generic/backport-4.14/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch @@ -0,0 +1,70 @@ +From 074a1e1167afd82c26f6d03a9a8b997d564bb241 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 28 May 2019 17:05:03 +0000 +Subject: [PATCH] MIPS: Bounds check virt_addr_valid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virt_addr_valid() function is meant to return true iff +virt_to_page() will return a valid struct page reference. This is true +iff the address provided is found within the unmapped address range +between PAGE_OFFSET & MAP_BASE, but we don't currently check for that +condition. Instead we simply mask the address to obtain what will be a +physical address if the virtual address is indeed in the desired range, +shift it to form a PFN & then call pfn_valid(). This can incorrectly +return true if called with a virtual address which, after masking, +happens to form a physical address corresponding to a valid PFN. + +For example we may vmalloc an address in the kernel mapped region +starting a MAP_BASE & obtain the virtual address: + + addr = 0xc000000000002000 + +When masked by virt_to_phys(), which uses __pa() & in turn CPHYSADDR(), +we obtain the following (bogus) physical address: + + addr = 0x2000 + +In a common system with PHYS_OFFSET=0 this will correspond to a valid +struct page which should really be accessed by virtual address +PAGE_OFFSET+0x2000, causing virt_addr_valid() to incorrectly return 1 +indicating that the original address corresponds to a struct page. + +This is equivalent to the ARM64 change made in commit ca219452c6b8 +("arm64: Correctly bounds check virt_addr_valid"). + +This fixes fallout when hardened usercopy is enabled caused by the +related commit 517e1fbeb65f ("mm/usercopy: Drop extra +is_vmalloc_or_module() check") which removed a check for the vmalloc +range that was present from the introduction of the hardened usercopy +feature. + +Signed-off-by: Paul Burton +References: ca219452c6b8 ("arm64: Correctly bounds check virt_addr_valid") +References: 517e1fbeb65f ("mm/usercopy: Drop extra is_vmalloc_or_module() check") +Reported-by: Julien Cristau +Reviewed-by: Philippe Mathieu-Daudé +Tested-by: YunQiang Su +URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929366 +Cc: stable@vger.kernel.org # v4.12+ +Cc: linux-mips@vger.kernel.org +Cc: Yunqiang Su +--- + arch/mips/mm/mmap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/mips/mm/mmap.c ++++ b/arch/mips/mm/mmap.c +@@ -203,6 +203,11 @@ unsigned long arch_randomize_brk(struct + + int __virt_addr_valid(const volatile void *kaddr) + { ++ unsigned long vaddr = (unsigned long)vaddr; ++ ++ if ((vaddr < PAGE_OFFSET) || (vaddr >= MAP_BASE)) ++ return 0; ++ + return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); + } + EXPORT_SYMBOL_GPL(__virt_addr_valid); diff --git a/target/linux/generic/backport-4.19/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch b/target/linux/generic/backport-4.19/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch new file mode 100644 index 0000000000..028e84a691 --- /dev/null +++ b/target/linux/generic/backport-4.19/430-v5.2-MIPS-Bounds-check-virt_addr_valid.patch @@ -0,0 +1,70 @@ +From 074a1e1167afd82c26f6d03a9a8b997d564bb241 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 28 May 2019 17:05:03 +0000 +Subject: [PATCH] MIPS: Bounds check virt_addr_valid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virt_addr_valid() function is meant to return true iff +virt_to_page() will return a valid struct page reference. This is true +iff the address provided is found within the unmapped address range +between PAGE_OFFSET & MAP_BASE, but we don't currently check for that +condition. Instead we simply mask the address to obtain what will be a +physical address if the virtual address is indeed in the desired range, +shift it to form a PFN & then call pfn_valid(). This can incorrectly +return true if called with a virtual address which, after masking, +happens to form a physical address corresponding to a valid PFN. + +For example we may vmalloc an address in the kernel mapped region +starting a MAP_BASE & obtain the virtual address: + + addr = 0xc000000000002000 + +When masked by virt_to_phys(), which uses __pa() & in turn CPHYSADDR(), +we obtain the following (bogus) physical address: + + addr = 0x2000 + +In a common system with PHYS_OFFSET=0 this will correspond to a valid +struct page which should really be accessed by virtual address +PAGE_OFFSET+0x2000, causing virt_addr_valid() to incorrectly return 1 +indicating that the original address corresponds to a struct page. + +This is equivalent to the ARM64 change made in commit ca219452c6b8 +("arm64: Correctly bounds check virt_addr_valid"). + +This fixes fallout when hardened usercopy is enabled caused by the +related commit 517e1fbeb65f ("mm/usercopy: Drop extra +is_vmalloc_or_module() check") which removed a check for the vmalloc +range that was present from the introduction of the hardened usercopy +feature. + +Signed-off-by: Paul Burton +References: ca219452c6b8 ("arm64: Correctly bounds check virt_addr_valid") +References: 517e1fbeb65f ("mm/usercopy: Drop extra is_vmalloc_or_module() check") +Reported-by: Julien Cristau +Reviewed-by: Philippe Mathieu-Daudé +Tested-by: YunQiang Su +URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929366 +Cc: stable@vger.kernel.org # v4.12+ +Cc: linux-mips@vger.kernel.org +Cc: Yunqiang Su +--- + arch/mips/mm/mmap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/mips/mm/mmap.c ++++ b/arch/mips/mm/mmap.c +@@ -203,6 +203,11 @@ unsigned long arch_randomize_brk(struct + + int __virt_addr_valid(const volatile void *kaddr) + { ++ unsigned long vaddr = (unsigned long)vaddr; ++ ++ if ((vaddr < PAGE_OFFSET) || (vaddr >= MAP_BASE)) ++ return 0; ++ + return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); + } + EXPORT_SYMBOL_GPL(__virt_addr_valid);