^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Flexible mmap layout support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Based on code by Ingo Molnar and Andi Kleen, copyrighted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright 2003-2009 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright 2005 Andi Kleen, SUSE Labs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright 2007 Jiri Kosina, SUSE Labs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/elf-randomize.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "physaddr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct va_alignment __read_mostly va_align = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .flags = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned long task_size_32bit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return IA32_PAGE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long task_size_64bit(int full_addr_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return full_addr_space ? TASK_SIZE_MAX : DEFAULT_MAP_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static unsigned long stack_maxrandom_size(unsigned long task_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned long max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (current->flags & PF_RANDOMIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) max = (-1UL) & __STACK_RND_MASK(task_size == task_size_32bit());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) max <<= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) # define mmap32_rnd_bits mmap_rnd_compat_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) # define mmap64_rnd_bits mmap_rnd_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # define mmap32_rnd_bits mmap_rnd_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) # define mmap64_rnd_bits mmap_rnd_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SIZE_128M (128 * 1024 * 1024UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int mmap_is_legacy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (current->personality & ADDR_COMPAT_LAYOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return sysctl_legacy_va_layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static unsigned long arch_rnd(unsigned int rndbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!(current->flags & PF_RANDOMIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return (get_random_long() & ((1UL << rndbits) - 1)) << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned long arch_mmap_rnd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct rlimit *rlim_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned long gap = rlim_stack->rlim_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned long pad = stack_maxrandom_size(task_size) + stack_guard_gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long gap_min, gap_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Values close to RLIM_INFINITY can overflow. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (gap + pad > gap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) gap += pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Top of mmap area (just below the process stack).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Leave an at least ~128 MB hole with possible stack randomization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) gap_min = SIZE_128M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) gap_max = (task_size / 6) * 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (gap < gap_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) gap = gap_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) else if (gap > gap_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) gap = gap_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return PAGE_ALIGN(task_size - gap - rnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static unsigned long mmap_legacy_base(unsigned long rnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned long task_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return __TASK_UNMAPPED_BASE(task_size) + rnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * This function, called very early during the creation of a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * process VM image, sets up which VM layout function to use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned long random_factor, unsigned long task_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct rlimit *rlim_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *legacy_base = mmap_legacy_base(random_factor, task_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (mmap_is_legacy())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *base = *legacy_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *base = mmap_base(random_factor, task_size, rlim_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (mmap_is_legacy())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mm->get_unmapped_area = arch_get_unmapped_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mm->get_unmapped_area = arch_get_unmapped_area_topdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) arch_rnd(mmap64_rnd_bits), task_size_64bit(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rlim_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * The mmap syscall mapping base decision depends solely on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * syscall type (64-bit or compat). This applies for 64bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * applications and 32bit applications. The 64bit syscall uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * mmap_base, the compat syscall uses mmap_compat_base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) arch_rnd(mmap32_rnd_bits), task_size_32bit(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) rlim_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned long get_mmap_base(int is_legacy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (in_32bit_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return is_legacy ? mm->mmap_compat_legacy_base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) : mm->mmap_compat_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return is_legacy ? mm->mmap_legacy_base : mm->mmap_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) const char *arch_vma_name(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * mmap_address_hint_valid - Validate the address hint of mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @addr: Address hint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @len: Mapping length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Check whether @addr and @addr + @len result in a valid mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * On 32bit this only checks whether @addr + @len is <= TASK_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * On 64bit with 5-level page tables another sanity check is required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * because mappings requested by mmap(@addr, 0) which cross the 47-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * virtual address boundary can cause the following theoretical issue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * An application calls mmap(addr, 0), i.e. without MAP_FIXED, where @addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * is below the border of the 47-bit address space and @addr + @len is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * above the border.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * With 4-level paging this request succeeds, but the resulting mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * address will always be within the 47-bit virtual address space, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * the hint address does not result in a valid mapping and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * ignored. Hence applications which are not prepared to handle virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * addresses above 47-bit work correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * With 5-level paging this request would be granted and result in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * mapping which crosses the border of the 47-bit virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * space. If the application cannot handle addresses above 47-bit this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * will lead to misbehaviour and hard to diagnose failures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Therefore ignore address hints which would result in a mapping crossing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * the 47-bit virtual address boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Note, that in the same scenario with MAP_FIXED the behaviour is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * different. The request with @addr < 47-bit and @addr + @len > 47-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * fails on a 4-level paging machine but succeeds on a 5-level paging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * machine. It is reasonable to expect that an application does not rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * the failure of such a fixed mapping request, so the restriction is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * applied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) bool mmap_address_hint_valid(unsigned long addr, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (TASK_SIZE - len < addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return (addr > DEFAULT_MAP_WINDOW) == (addr + len > DEFAULT_MAP_WINDOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Can we access it for direct reading/writing? Must be RAM: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int valid_phys_addr_range(phys_addr_t addr, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return addr + count - 1 <= __pa(high_memory - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Can we access it through mmap? Must be a valid physical address: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return phys_addr_valid(addr + count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * Only allow root to set high MMIO mappings to PROT_NONE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * This prevents an unpriv. user to set them to PROT_NONE and invert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * them, then pointing to valid memory for L1TF speculation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Note: for locked down kernels may want to disable the root override.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!boot_cpu_has_bug(X86_BUG_L1TF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!__pte_needs_invert(pgprot_val(prot)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* If it's real memory always allow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (pfn_valid(pfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (pfn >= l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }