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, 1 Feb 2022 18:14:19 +0100
From:   Borys Popławski <poplawski.borys@...il.com>
To:     luto@...nel.org
Cc:     linux-kernel@...r.kernel.org
Subject: VDSO is randomized even when ASLR is disabled

Hello,
I've stumbled upon an issue of VDSO address being randomized on x86_64 when ASLR is disabled. This happens only on systems with 5-level paging enabled. Details below.

Relevant code: "vdso_addr" in arch/x86/entry/vdso/vma.c
VDSO base address is picked at random starting from the stack bottom address so that it stays in the same PMD as the stack. This randomization is made regardless of PF_RANDOMIZE flag.
With ASLR off, stack is mapped at the highest possible address in 4-level paging, which is 0x7ffffffff000 - this leaves no space for VDSO after the stack, which effectively disables the above randomization. With 5-level paging the stack address stays the same, but "TASK_SIZE_MAX" is much greater, allowing for the above randomization.

This behavior is present in all versions (since VDSO was introduced on x64). I think the fix could be as simple as:

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 235a5794296a..0bc83e4ca512 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -326,7 +326,7 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
                end = TASK_SIZE_MAX;
        end -= len;
 
-       if (end > start) {
+       if (end > start && (current->flags & PF_RANDOMIZE)) {
                offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
                addr = start + (offset << PAGE_SHIFT);
        } else {

but I've not tested it yet, figured I'll post here first.

Best regards,
Borys

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ