linux/mm/mprotect.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  mm/mprotect.c
   4 *
   5 *  (C) Copyright 1994 Linus Torvalds
   6 *  (C) Copyright 2002 Christoph Hellwig
   7 *
   8 *  Address space accounting code       <alan@lxorguk.ukuu.org.uk>
   9 *  (C) Copyright 2002 Red Hat Inc, All Rights Reserved
  10 */
  11
  12#include <linux/mm.h>
  13#include <linux/hugetlb.h>
  14#include <linux/shm.h>
  15#include <linux/mman.h>
  16#include <linux/fs.h>
  17#include <linux/highmem.h>
  18#include <linux/security.h>
  19#include <linux/mempolicy.h>
  20#include <linux/personality.h>
  21#include <linux/syscalls.h>
  22#include <linux/swap.h>
  23#include <linux/swapops.h>
  24#include <linux/mmu_notifier.h>
  25#include <linux/migrate.h>
  26#include <linux/perf_event.h>
  27#include <linux/pkeys.h>
  28#include <linux/ksm.h>
  29#include <linux/uaccess.h>
  30#include <asm/pgtable.h>
  31#include <asm/cacheflush.h>
  32#include <asm/mmu_context.h>
  33#include <asm/tlbflush.h>
  34
  35#include "internal.h"
  36
  37static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
  38                unsigned long addr, unsigned long end, pgprot_t newprot,
  39                int dirty_accountable, int prot_numa)
  40{
  41        struct mm_struct *mm = vma->vm_mm;
  42        pte_t *pte, oldpte;
  43        spinlock_t *ptl;
  44        unsigned long pages = 0;
  45        int target_node = NUMA_NO_NODE;
  46
  47        /*
  48         * Can be called with only the mmap_sem for reading by
  49         * prot_numa so we must check the pmd isn't constantly
  50         * changing from under us from pmd_none to pmd_trans_huge
  51         * and/or the other way around.
  52         */
  53        if (pmd_trans_unstable(pmd))
  54                return 0;
  55
  56        /*
  57         * The pmd points to a regular pte so the pmd can't change
  58         * from under us even if the mmap_sem is only hold for
  59         * reading.
  60         */
  61        pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
  62
  63        /* Get target node for single threaded private VMAs */
  64        if (prot_numa && !(vma->vm_flags & VM_SHARED) &&
  65            atomic_read(&vma->vm_mm->mm_users) == 1)
  66                target_node = numa_node_id();
  67
  68        flush_tlb_batched_pending(vma->vm_mm);
  69        arch_enter_lazy_mmu_mode();
  70        do {
  71                oldpte = *pte;
  72                if (pte_present(oldpte)) {
  73                        pte_t ptent;
  74                        bool preserve_write = prot_numa && pte_write(oldpte);
  75
  76                        /*
  77                         * Avoid trapping faults against the zero or KSM
  78                         * pages. See similar comment in change_huge_pmd.
  79                         */
  80                        if (prot_numa) {
  81                                struct page *page;
  82
  83                                page = vm_normal_page(vma, addr, oldpte);
  84                                if (!page || PageKsm(page))
  85                                        continue;
  86
  87                                /* Also skip shared copy-on-write pages */
  88                                if (is_cow_mapping(vma->vm_flags) &&
  89                                    page_mapcount(page) != 1)
  90                                        continue;
  91
  92                                /* Avoid TLB flush if possible */
  93                                if (pte_protnone(oldpte))
  94                                        continue;
  95
  96                                /*
  97                                 * Don't mess with PTEs if page is already on the node
  98                                 * a single-threaded process is running on.
  99                                 */
 100                                if (target_node == page_to_nid(page))
 101                                        continue;
 102                        }
 103
 104                        ptent = ptep_modify_prot_start(mm, addr, pte);
 105                        ptent = pte_modify(ptent, newprot);
 106                        if (preserve_write)
 107                                ptent = pte_mk_savedwrite(ptent);
 108
 109                        /* Avoid taking write faults for known dirty pages */
 110                        if (dirty_accountable && pte_dirty(ptent) &&
 111                                        (pte_soft_dirty(ptent) ||
 112                                         !(vma->vm_flags & VM_SOFTDIRTY))) {
 113                                ptent = pte_mkwrite(ptent);
 114                        }
 115                        ptep_modify_prot_commit(mm, addr, pte, ptent);
 116                        pages++;
 117                } else if (IS_ENABLED(CONFIG_MIGRATION)) {
 118                        swp_entry_t entry = pte_to_swp_entry(oldpte);
 119
 120                        if (is_write_migration_entry(entry)) {
 121                                pte_t newpte;
 122                                /*
 123                                 * A protection check is difficult so
 124                                 * just be safe and disable write
 125                                 */
 126                                make_migration_entry_read(&entry);
 127                                newpte = swp_entry_to_pte(entry);
 128                                if (pte_swp_soft_dirty(oldpte))
 129                                        newpte = pte_swp_mksoft_dirty(newpte);
 130                                set_pte_at(mm, addr, pte, newpte);
 131
 132                                pages++;
 133                        }
 134
 135                        if (is_write_device_private_entry(entry)) {
 136                                pte_t newpte;
 137
 138                                /*
 139                                 * We do not preserve soft-dirtiness. See
 140                                 * copy_one_pte() for explanation.
 141                                 */
 142                                make_device_private_entry_read(&entry);
 143                                newpte = swp_entry_to_pte(entry);
 144                                set_pte_at(mm, addr, pte, newpte);
 145
 146                                pages++;
 147                        }
 148                }
 149        } while (pte++, addr += PAGE_SIZE, addr != end);
 150        arch_leave_lazy_mmu_mode();
 151        pte_unmap_unlock(pte - 1, ptl);
 152
 153        return pages;
 154}
 155
 156static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
 157                pud_t *pud, unsigned long addr, unsigned long end,
 158                pgprot_t newprot, int dirty_accountable, int prot_numa)
 159{
 160        pmd_t *pmd;
 161        struct mm_struct *mm = vma->vm_mm;
 162        unsigned long next;
 163        unsigned long pages = 0;
 164        unsigned long nr_huge_updates = 0;
 165        unsigned long mni_start = 0;
 166
 167        pmd = pmd_offset(pud, addr);
 168        do {
 169                unsigned long this_pages;
 170
 171                next = pmd_addr_end(addr, end);
 172                if (!is_swap_pmd(*pmd) && !pmd_trans_huge(*pmd) && !pmd_devmap(*pmd)
 173                                && pmd_none_or_clear_bad(pmd))
 174                        goto next;
 175
 176                /* invoke the mmu notifier if the pmd is populated */
 177                if (!mni_start) {
 178                        mni_start = addr;
 179                        mmu_notifier_invalidate_range_start(mm, mni_start, end);
 180                }
 181
 182                if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
 183                        if (next - addr != HPAGE_PMD_SIZE) {
 184                                __split_huge_pmd(vma, pmd, addr, false, NULL);
 185                        } else {
 186                                int nr_ptes = change_huge_pmd(vma, pmd, addr,
 187                                                newprot, prot_numa);
 188
 189                                if (nr_ptes) {
 190                                        if (nr_ptes == HPAGE_PMD_NR) {
 191                                                pages += HPAGE_PMD_NR;
 192                                                nr_huge_updates++;
 193                                        }
 194
 195                                        /* huge pmd was handled */
 196                                        goto next;
 197                                }
 198                        }
 199                        /* fall through, the trans huge pmd just split */
 200                }
 201                this_pages = change_pte_range(vma, pmd, addr, next, newprot,
 202                                 dirty_accountable, prot_numa);
 203                pages += this_pages;
 204next:
 205                cond_resched();
 206        } while (pmd++, addr = next, addr != end);
 207
 208        if (mni_start)
 209                mmu_notifier_invalidate_range_end(mm, mni_start, end);
 210
 211        if (nr_huge_updates)
 212                count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates);
 213        return pages;
 214}
 215
 216static inline unsigned long change_pud_range(struct vm_area_struct *vma,
 217                p4d_t *p4d, unsigned long addr, unsigned long end,
 218                pgprot_t newprot, int dirty_accountable, int prot_numa)
 219{
 220        pud_t *pud;
 221        unsigned long next;
 222        unsigned long pages = 0;
 223
 224        pud = pud_offset(p4d, addr);
 225        do {
 226                next = pud_addr_end(addr, end);
 227                if (pud_none_or_clear_bad(pud))
 228                        continue;
 229                pages += change_pmd_range(vma, pud, addr, next, newprot,
 230                                 dirty_accountable, prot_numa);
 231        } while (pud++, addr = next, addr != end);
 232
 233        return pages;
 234}
 235
 236static inline unsigned long change_p4d_range(struct vm_area_struct *vma,
 237                pgd_t *pgd, unsigned long addr, unsigned long end,
 238                pgprot_t newprot, int dirty_accountable, int prot_numa)
 239{
 240        p4d_t *p4d;
 241        unsigned long next;
 242        unsigned long pages = 0;
 243
 244        p4d = p4d_offset(pgd, addr);
 245        do {
 246                next = p4d_addr_end(addr, end);
 247                if (p4d_none_or_clear_bad(p4d))
 248                        continue;
 249                pages += change_pud_range(vma, p4d, addr, next, newprot,
 250                                 dirty_accountable, prot_numa);
 251        } while (p4d++, addr = next, addr != end);
 252
 253        return pages;
 254}
 255
 256static unsigned long change_protection_range(struct vm_area_struct *vma,
 257                unsigned long addr, unsigned long end, pgprot_t newprot,
 258                int dirty_accountable, int prot_numa)
 259{
 260        struct mm_struct *mm = vma->vm_mm;
 261        pgd_t *pgd;
 262        unsigned long next;
 263        unsigned long start = addr;
 264        unsigned long pages = 0;
 265
 266        BUG_ON(addr >= end);
 267        pgd = pgd_offset(mm, addr);
 268        flush_cache_range(vma, addr, end);
 269        inc_tlb_flush_pending(mm);
 270        do {
 271                next = pgd_addr_end(addr, end);
 272                if (pgd_none_or_clear_bad(pgd))
 273                        continue;
 274                pages += change_p4d_range(vma, pgd, addr, next, newprot,
 275                                 dirty_accountable, prot_numa);
 276        } while (pgd++, addr = next, addr != end);
 277
 278        /* Only flush the TLB if we actually modified any entries: */
 279        if (pages)
 280                flush_tlb_range(vma, start, end);
 281        dec_tlb_flush_pending(mm);
 282
 283        return pages;
 284}
 285
 286unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,
 287                       unsigned long end, pgprot_t newprot,
 288                       int dirty_accountable, int prot_numa)
 289{
 290        unsigned long pages;
 291
 292        if (is_vm_hugetlb_page(vma))
 293                pages = hugetlb_change_protection(vma, start, end, newprot);
 294        else
 295                pages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa);
 296
 297        return pages;
 298}
 299
 300int
 301mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 302        unsigned long start, unsigned long end, unsigned long newflags)
 303{
 304        struct mm_struct *mm = vma->vm_mm;
 305        unsigned long oldflags = vma->vm_flags;
 306        long nrpages = (end - start) >> PAGE_SHIFT;
 307        unsigned long charged = 0;
 308        pgoff_t pgoff;
 309        int error;
 310        int dirty_accountable = 0;
 311
 312        if (newflags == oldflags) {
 313                *pprev = vma;
 314                return 0;
 315        }
 316
 317        /*
 318         * If we make a private mapping writable we increase our commit;
 319         * but (without finer accounting) cannot reduce our commit if we
 320         * make it unwritable again. hugetlb mapping were accounted for
 321         * even if read-only so there is no need to account for them here
 322         */
 323        if (newflags & VM_WRITE) {
 324                /* Check space limits when area turns into data. */
 325                if (!may_expand_vm(mm, newflags, nrpages) &&
 326                                may_expand_vm(mm, oldflags, nrpages))
 327                        return -ENOMEM;
 328                if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB|
 329                                                VM_SHARED|VM_NORESERVE))) {
 330                        charged = nrpages;
 331                        if (security_vm_enough_memory_mm(mm, charged))
 332                                return -ENOMEM;
 333                        newflags |= VM_ACCOUNT;
 334                }
 335        }
 336
 337        /*
 338         * First try to merge with previous and/or next vma.
 339         */
 340        pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
 341        *pprev = vma_merge(mm, *pprev, start, end, newflags,
 342                           vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
 343                           vma->vm_userfaultfd_ctx);
 344        if (*pprev) {
 345                vma = *pprev;
 346                VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY);
 347                goto success;
 348        }
 349
 350        *pprev = vma;
 351
 352        if (start != vma->vm_start) {
 353                error = split_vma(mm, vma, start, 1);
 354                if (error)
 355                        goto fail;
 356        }
 357
 358        if (end != vma->vm_end) {
 359                error = split_vma(mm, vma, end, 0);
 360                if (error)
 361                        goto fail;
 362        }
 363
 364success:
 365        /*
 366         * vm_flags and vm_page_prot are protected by the mmap_sem
 367         * held in write mode.
 368         */
 369        vma->vm_flags = newflags;
 370        dirty_accountable = vma_wants_writenotify(vma, vma->vm_page_prot);
 371        vma_set_page_prot(vma);
 372
 373        change_protection(vma, start, end, vma->vm_page_prot,
 374                          dirty_accountable, 0);
 375
 376        /*
 377         * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 378         * fault on access.
 379         */
 380        if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
 381                        (newflags & VM_WRITE)) {
 382                populate_vma_page_range(vma, start, end, NULL);
 383        }
 384
 385        vm_stat_account(mm, oldflags, -nrpages);
 386        vm_stat_account(mm, newflags, nrpages);
 387        perf_event_mmap(vma);
 388        return 0;
 389
 390fail:
 391        vm_unacct_memory(charged);
 392        return error;
 393}
 394
 395/*
 396 * pkey==-1 when doing a legacy mprotect()
 397 */
 398static int do_mprotect_pkey(unsigned long start, size_t len,
 399                unsigned long prot, int pkey)
 400{
 401        unsigned long nstart, end, tmp, reqprot;
 402        struct vm_area_struct *vma, *prev;
 403        int error = -EINVAL;
 404        const int grows = prot & (PROT_GROWSDOWN|PROT_GROWSUP);
 405        const bool rier = (current->personality & READ_IMPLIES_EXEC) &&
 406                                (prot & PROT_READ);
 407
 408        prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP);
 409        if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */
 410                return -EINVAL;
 411
 412        if (start & ~PAGE_MASK)
 413                return -EINVAL;
 414        if (!len)
 415                return 0;
 416        len = PAGE_ALIGN(len);
 417        end = start + len;
 418        if (end <= start)
 419                return -ENOMEM;
 420        if (!arch_validate_prot(prot))
 421                return -EINVAL;
 422
 423        reqprot = prot;
 424
 425        if (down_write_killable(&current->mm->mmap_sem))
 426                return -EINTR;
 427
 428        /*
 429         * If userspace did not allocate the pkey, do not let
 430         * them use it here.
 431         */
 432        error = -EINVAL;
 433        if ((pkey != -1) && !mm_pkey_is_allocated(current->mm, pkey))
 434                goto out;
 435
 436        vma = find_vma(current->mm, start);
 437        error = -ENOMEM;
 438        if (!vma)
 439                goto out;
 440        prev = vma->vm_prev;
 441        if (unlikely(grows & PROT_GROWSDOWN)) {
 442                if (vma->vm_start >= end)
 443                        goto out;
 444                start = vma->vm_start;
 445                error = -EINVAL;
 446                if (!(vma->vm_flags & VM_GROWSDOWN))
 447                        goto out;
 448        } else {
 449                if (vma->vm_start > start)
 450                        goto out;
 451                if (unlikely(grows & PROT_GROWSUP)) {
 452                        end = vma->vm_end;
 453                        error = -EINVAL;
 454                        if (!(vma->vm_flags & VM_GROWSUP))
 455                                goto out;
 456                }
 457        }
 458        if (start > vma->vm_start)
 459                prev = vma;
 460
 461        for (nstart = start ; ; ) {
 462                unsigned long mask_off_old_flags;
 463                unsigned long newflags;
 464                int new_vma_pkey;
 465
 466                /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
 467
 468                /* Does the application expect PROT_READ to imply PROT_EXEC */
 469                if (rier && (vma->vm_flags & VM_MAYEXEC))
 470                        prot |= PROT_EXEC;
 471
 472                /*
 473                 * Each mprotect() call explicitly passes r/w/x permissions.
 474                 * If a permission is not passed to mprotect(), it must be
 475                 * cleared from the VMA.
 476                 */
 477                mask_off_old_flags = VM_READ | VM_WRITE | VM_EXEC |
 478                                        ARCH_VM_PKEY_FLAGS;
 479
 480                new_vma_pkey = arch_override_mprotect_pkey(vma, prot, pkey);
 481                newflags = calc_vm_prot_bits(prot, new_vma_pkey);
 482                newflags |= (vma->vm_flags & ~mask_off_old_flags);
 483
 484                /* newflags >> 4 shift VM_MAY% in place of VM_% */
 485                if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
 486                        error = -EACCES;
 487                        goto out;
 488                }
 489
 490                error = security_file_mprotect(vma, reqprot, prot);
 491                if (error)
 492                        goto out;
 493
 494                tmp = vma->vm_end;
 495                if (tmp > end)
 496                        tmp = end;
 497                error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
 498                if (error)
 499                        goto out;
 500                nstart = tmp;
 501
 502                if (nstart < prev->vm_end)
 503                        nstart = prev->vm_end;
 504                if (nstart >= end)
 505                        goto out;
 506
 507                vma = prev->vm_next;
 508                if (!vma || vma->vm_start != nstart) {
 509                        error = -ENOMEM;
 510                        goto out;
 511                }
 512                prot = reqprot;
 513        }
 514out:
 515        up_write(&current->mm->mmap_sem);
 516        return error;
 517}
 518
 519SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
 520                unsigned long, prot)
 521{
 522        return do_mprotect_pkey(start, len, prot, -1);
 523}
 524
 525#ifdef CONFIG_ARCH_HAS_PKEYS
 526
 527SYSCALL_DEFINE4(pkey_mprotect, unsigned long, start, size_t, len,
 528                unsigned long, prot, int, pkey)
 529{
 530        return do_mprotect_pkey(start, len, prot, pkey);
 531}
 532
 533SYSCALL_DEFINE2(pkey_alloc, unsigned long, flags, unsigned long, init_val)
 534{
 535        int pkey;
 536        int ret;
 537
 538        /* No flags supported yet. */
 539        if (flags)
 540                return -EINVAL;
 541        /* check for unsupported init values */
 542        if (init_val & ~PKEY_ACCESS_MASK)
 543                return -EINVAL;
 544
 545        down_write(&current->mm->mmap_sem);
 546        pkey = mm_pkey_alloc(current->mm);
 547
 548        ret = -ENOSPC;
 549        if (pkey == -1)
 550                goto out;
 551
 552        ret = arch_set_user_pkey_access(current, pkey, init_val);
 553        if (ret) {
 554                mm_pkey_free(current->mm, pkey);
 555                goto out;
 556        }
 557        ret = pkey;
 558out:
 559        up_write(&current->mm->mmap_sem);
 560        return ret;
 561}
 562
 563SYSCALL_DEFINE1(pkey_free, int, pkey)
 564{
 565        int ret;
 566
 567        down_write(&current->mm->mmap_sem);
 568        ret = mm_pkey_free(current->mm, pkey);
 569        up_write(&current->mm->mmap_sem);
 570
 571        /*
 572         * We could provie warnings or errors if any VMA still
 573         * has the pkey set here.
 574         */
 575        return ret;
 576}
 577
 578#endif /* CONFIG_ARCH_HAS_PKEYS */
 579