From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-by2nam03on0101.outbound.protection.outlook.com ([104.47.42.101]:17968 "EHLO NAM03-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S935138AbeCHE61 (ORCPT ); Wed, 7 Mar 2018 23:58:27 -0500 From: Sasha Levin To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: Kees Cook , Greg Kroah-Hartman , Sasha Levin Subject: [PATCH AUTOSEL for 4.14 30/67] /dev/mem: Add bounce buffer for copy-out Date: Thu, 8 Mar 2018 04:57:44 +0000 Message-ID: <20180308045641.7814-30-alexander.levin@microsoft.com> References: <20180308045641.7814-1-alexander.levin@microsoft.com> In-Reply-To: <20180308045641.7814-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Kees Cook [ Upstream commit 22ec1a2aea73b9dfe340dff7945bd85af4cc6280 ] As done for /proc/kcore in commit df04abfd181a ("fs/proc/kcore.c: Add bounce buffer for ktext data") this adds a bounce buffer when reading memory via /dev/mem. This is needed to allow kernel text memory to be read out when built with CONFIG_HARDENED_USERCOPY (which refuses to read out kernel text) and without CONFIG_STRICT_DEVMEM (which would have refused to read any RAM contents at all). Since this build configuration isn't common (most systems with CONFIG_HARDENED_USERCOPY also have CONFIG_STRICT_DEVMEM), this also tries to inform Kconfig about the recommended settings. This patch is modified from Brad Spengler/PaX Team's changes to /dev/mem code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. Reported-by: Michael Holzheu Fixes: f5509cc18daa ("mm: Hardened usercopy") Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/char/mem.c | 27 ++++++++++++++++++++++----- security/Kconfig | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 970e1242a282..3a70dba2c645 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -107,6 +107,8 @@ static ssize_t read_mem(struct file *file, char __user = *buf, phys_addr_t p =3D *ppos; ssize_t read, sz; void *ptr; + char *bounce; + int err; =20 if (p !=3D *ppos) return 0; @@ -129,15 +131,22 @@ static ssize_t read_mem(struct file *file, char __use= r *buf, } #endif =20 + bounce =3D kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!bounce) + return -ENOMEM; + while (count > 0) { unsigned long remaining; int allowed; =20 sz =3D size_inside_page(p, count); =20 + err =3D -EPERM; allowed =3D page_is_allowed(p >> PAGE_SHIFT); if (!allowed) - return -EPERM; + goto failed; + + err =3D -EFAULT; if (allowed =3D=3D 2) { /* Show zeros for restricted memory. */ remaining =3D clear_user(buf, sz); @@ -149,24 +158,32 @@ static ssize_t read_mem(struct file *file, char __use= r *buf, */ ptr =3D xlate_dev_mem_ptr(p); if (!ptr) - return -EFAULT; - - remaining =3D copy_to_user(buf, ptr, sz); + goto failed; =20 + err =3D probe_kernel_read(bounce, ptr, sz); unxlate_dev_mem_ptr(p, ptr); + if (err) + goto failed; + + remaining =3D copy_to_user(buf, bounce, sz); } =20 if (remaining) - return -EFAULT; + goto failed; =20 buf +=3D sz; p +=3D sz; count -=3D sz; read +=3D sz; } + kfree(bounce); =20 *ppos +=3D read; return read; + +failed: + kfree(bounce); + return err; } =20 static ssize_t write_mem(struct file *file, const char __user *buf, diff --git a/security/Kconfig b/security/Kconfig index b5c2b5d0c6c0..87f2a6f842fd 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -154,6 +154,7 @@ config HARDENED_USERCOPY bool "Harden memory copies between kernel and userspace" depends on HAVE_HARDENED_USERCOPY_ALLOCATOR select BUG + imply STRICT_DEVMEM help This option checks for obviously wrong memory regions when copying memory to/from the kernel (via copy_to_user() and --=20 2.14.1