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>] [day] [month] [year] [list]
Message-Id: <20230529125709.1882042-1-mwk@0x04.net>
Date:   Mon, 29 May 2023 14:57:09 +0200
From:   Marcelina Kościelnicka <mwk@...4.net>
To:     linux-kernel@...r.kernel.org
Cc:     Andy Lutomirski <luto@...nel.org>,
        Marcelina Kościelnicka <mwk@...4.net>
Subject: [PATCH] x86/vdso: Limit vdso allocation to 47-bit address space

The vdso is normally allocated after the stack, with a random offset.
With ADDR_NO_RANDOMIZE and without 57-bit virtual addressing, the stack is
too close to the canonical address hole to fit the vdso after it, so it
reverts to normal mmap handling, resulting in something like the
following (deterministic) address map:

[...]
7ffff7fc4000-7ffff7fc8000 r--p 00000000 00:00 0                          [vvar]
7ffff7fc8000-7ffff7fca000 r-xp 00000000 00:00 0                          [vdso]
7ffff7fca000-7ffff7fcb000 r--p 00000000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7fcb000-7ffff7ff1000 r-xp 00001000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ff1000-7ffff7ffb000 r--p 00027000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ffb000-7ffff7ffd000 r--p 00031000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ffd000-7ffff7fff000 rw-p 00033000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

However, on a CPU with LA57 support, allocating the vdso after the stack
actually succeeds and results in something like the following:

[...]
7ffff7fca000-7ffff7fcb000 r--p 00000000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7fcb000-7ffff7ff1000 r-xp 00001000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ff1000-7ffff7ffb000 r--p 00027000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ffb000-7ffff7ffd000 r--p 00031000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffff7ffd000-7ffff7fff000 rw-p 00033000 fe:01 1183001                    /usr/lib/ld-linux-x86-64.so.2
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
8000001be000-8000001c2000 r--p 00000000 00:00 0                          [vvar]
8000001c2000-8000001c4000 r-xp 00000000 00:00 0                          [vdso]

The resulting map has two problems:

1. The vdso mapping address is non-deterministic, since the
   get_random_u32_below call in vdso_addr is called unconditionally,
   without taking PF_RANDOMIZE into account.
2. The vdso is mapped outside of the legacy 47-bit address space,
   needlessly allocating 4 page tables and violating the principles
   outlined in Documentation/x86/x86_64/5level-paging.rst

This patch forces vdso allocation range to always be within the 47-bit
space, ensuring consistent results between LA57 and non-LA57 systems.

Signed-off-by: Marcelina Kościelnicka <mwk@...4.net>
---
 arch/x86/entry/vdso/vma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 2738eb28cb2e..1f4bdbadae1e 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -301,8 +301,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
 
 	/* Round the lowest possible end address up to a PMD boundary. */
 	end = (start + len + PMD_SIZE - 1) & PMD_MASK;
-	if (end >= TASK_SIZE_MAX)
-		end = TASK_SIZE_MAX;
+	if (end >= DEFAULT_MAP_WINDOW)
+		end = DEFAULT_MAP_WINDOW;
 	end -= len;
 
 	if (end > start) {
-- 
2.40.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ