LCOV - code coverage report
Current view: top level - arch/x86/mm - mmap.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 32 49 65.3 %
Date: 2022-03-28 13:20:08 Functions: 7 12 58.3 %
Branches: 14 48 29.2 %

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

Generated by: LCOV version 1.14