summaryrefslogtreecommitdiff
path: root/sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch')
-rw-r--r--sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch118
1 files changed, 118 insertions, 0 deletions
diff --git a/sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch b/sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch
new file mode 100644
index 000000000000..5e149a8c95e8
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.4/hardened-patches/0075-x86_64-move-vdso-to-mmap-region-from-stack-region.patch
@@ -0,0 +1,118 @@
+From ee13f3b984b979b264152d9ee1643d3f1ccf3fc9 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 11 May 2017 16:52:00 -0400
+Subject: [PATCH 075/112] x86_64: move vdso to mmap region from stack region
+
+This removes the only executable code from the stack region and gives
+the vdso the same randomized base as other mmap mappings including the
+linker and other shared objects. It results in a sane amount of entropy
+being provided and there's little to no advantage in separating this
+from the existing executable code there.
+
+It's sensible for userspace to reserve the initial mmap base as a region
+for executable code with a random gap for other mmap allocations, along
+with providing randomization within that region. However, there isn't
+much the kernel can do to help due to how dynamic linkers load the
+shared objects.
+
+This was extracted from the PaX RANDMMAP feature.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/entry/vdso/vma.c | 48 +-----------------------------------
+ arch/x86/include/asm/elf.h | 1 -
+ arch/x86/kernel/sys_x86_64.c | 7 ------
+ 3 files changed, 1 insertion(+), 55 deletions(-)
+
+diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
+index 9185cb1d13b9..543912071557 100644
+--- a/arch/x86/entry/vdso/vma.c
++++ b/arch/x86/entry/vdso/vma.c
+@@ -315,55 +315,9 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
+ }
+
+ #ifdef CONFIG_X86_64
+-/*
+- * Put the vdso above the (randomized) stack with another randomized
+- * offset. This way there is no hole in the middle of address space.
+- * To save memory make sure it is still in the same PTE as the stack
+- * top. This doesn't give that many random bits.
+- *
+- * Note that this algorithm is imperfect: the distribution of the vdso
+- * start address within a PMD is biased toward the end.
+- *
+- * Only used for the 64-bit and x32 vdsos.
+- */
+-static unsigned long vdso_addr(unsigned long start, unsigned len)
+-{
+- unsigned long addr, end;
+- unsigned offset;
+-
+- /*
+- * Round up the start address. It can start out unaligned as a result
+- * of stack start randomization.
+- */
+- start = PAGE_ALIGN(start);
+-
+- /* 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;
+- end -= len;
+-
+- if (end > start) {
+- offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
+- addr = start + (offset << PAGE_SHIFT);
+- } else {
+- addr = start;
+- }
+-
+- /*
+- * Forcibly align the final address in case we have a hardware
+- * issue that requires alignment for performance reasons.
+- */
+- addr = align_vdso_addr(addr);
+-
+- return addr;
+-}
+-
+ static int map_vdso_randomized(const struct vdso_image *image)
+ {
+- unsigned long addr = vdso_addr(current->mm->start_stack, image->size-image->sym_vvar_start);
+-
+- return map_vdso(image, addr);
++ return map_vdso(image, 0);
+ }
+ #endif
+
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index b55054566ece..58292600112d 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -398,5 +398,4 @@ struct va_alignment {
+ } ____cacheline_aligned;
+
+ extern struct va_alignment va_align;
+-extern unsigned long align_vdso_addr(unsigned long);
+ #endif /* _ASM_X86_ELF_H */
+diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
+index 504fa5425bce..c4e35a3b3733 100644
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -52,13 +52,6 @@ static unsigned long get_align_bits(void)
+ return va_align.bits & get_align_mask();
+ }
+
+-unsigned long align_vdso_addr(unsigned long addr)
+-{
+- unsigned long align_mask = get_align_mask();
+- addr = (addr + align_mask) & ~align_mask;
+- return addr | get_align_bits();
+-}
+-
+ static int __init control_va_addr_alignment(char *str)
+ {
+ /* guard against enabling this on other CPU families */
+--
+2.30.0
+