lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 19 Nov 2019 17:10:06 -0500
From:   Pavel Tatashin <pasha.tatashin@...een.com>
To:     pasha.tatashin@...een.com, jmorris@...ei.org, sashal@...nel.org,
        linux-kernel@...r.kernel.org, catalin.marinas@....com,
        will@...nel.org, steve.capper@....com,
        linux-arm-kernel@...ts.infradead.org, marc.zyngier@....com,
        james.morse@....com, vladimir.murzin@....com, mark.rutland@....com,
        tglx@...utronix.de, gregkh@...uxfoundation.org,
        allison@...utok.net, info@...ux.net, alexios.zavras@...el.com
Subject: [PATCH] arm64: kernel: memory corruptions due non-disabled PAN

Userland access functions (__arch_clear_user, __arch_copy_from_user,
__arch_copy_in_user, __arch_copy_to_user), enable and disable PAN
for the duration of copy. However, when copy fails for some reason,
i.e. access violation the code is transferred to fixedup section,
where we do not disable PAN.

The bug is a security violation as the access to userland is still
open when it should be disabled, but it also causes memory corruptions
when software emulated PAN is used: CONFIG_ARM64_SW_TTBR0_PAN=y.

I was able to reproduce memory corruption problem on Broadcom's SoC
ARMv8-A like this:

Enable software perf-events with PERF_SAMPLE_CALLCHAIN so userland's
stack is accessed and copied.

The test program performed the following on every CPU and forking many
processes:

	unsigned long *map = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
				  MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	map[0] = getpid();
	sched_yield();
	if (map[0] != getpid()) {
		fprintf(stderr, "Corruption detected!");
	}
	munmap(map, PAGE_SIZE);

>From time to time I was getting map[0] to contain pid for a different
process.

Fixes: 338d4f49d6f7114 ("arm64: kernel: Add support for Privileged...")

Signed-off-by: Pavel Tatashin <pasha.tatashin@...een.com>
---
 arch/arm64/lib/clear_user.S     | 1 +
 arch/arm64/lib/copy_from_user.S | 1 +
 arch/arm64/lib/copy_in_user.S   | 1 +
 arch/arm64/lib/copy_to_user.S   | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
index 10415572e82f..322b55664cca 100644
--- a/arch/arm64/lib/clear_user.S
+++ b/arch/arm64/lib/clear_user.S
@@ -48,5 +48,6 @@ EXPORT_SYMBOL(__arch_clear_user)
 	.section .fixup,"ax"
 	.align	2
 9:	mov	x0, x2			// return the original size
+	uaccess_disable_not_uao x2, x3
 	ret
 	.previous
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
index 680e74409ff9..8472dc7798b3 100644
--- a/arch/arm64/lib/copy_from_user.S
+++ b/arch/arm64/lib/copy_from_user.S
@@ -66,5 +66,6 @@ EXPORT_SYMBOL(__arch_copy_from_user)
 	.section .fixup,"ax"
 	.align	2
 9998:	sub	x0, end, dst			// bytes not copied
+	uaccess_disable_not_uao x3, x4
 	ret
 	.previous
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index 0bedae3f3792..8e0355c1e318 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -68,5 +68,6 @@ EXPORT_SYMBOL(__arch_copy_in_user)
 	.section .fixup,"ax"
 	.align	2
 9998:	sub	x0, end, dst			// bytes not copied
+	uaccess_disable_not_uao x3, x4
 	ret
 	.previous
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index 2d88c736e8f2..6085214654dc 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -65,5 +65,6 @@ EXPORT_SYMBOL(__arch_copy_to_user)
 	.section .fixup,"ax"
 	.align	2
 9998:	sub	x0, end, dst			// bytes not copied
+	uaccess_disable_not_uao x3, x4
 	ret
 	.previous
-- 
2.24.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ