1 /* 2 * mm/mprotect.c 3 * 4 * (C) Copyright 1994 Linus Torvalds 5 * (C) Copyright 2002 Christoph Hellwig 6 * 7 * Address space accounting code <alan@lxorguk.ukuu.org.uk> 8 * (C) Copyright 2002 Red Hat Inc, All Rights Reserved 9 */ 10 11 #include <linux/mm.h> 12 #include <linux/hugetlb.h> 13 #include <linux/shm.h> 14 #include <linux/mman.h> 15 #include <linux/fs.h> 16 #include <linux/highmem.h> 17 #include <linux/security.h> 18 #include <linux/mempolicy.h> 19 #include <linux/personality.h> 20 #include <linux/syscalls.h> 21 #include <linux/swap.h> 22 #include <linux/swapops.h> 23 #include <linux/mmu_notifier.h> 24 #include <linux/migrate.h> 25 #include <linux/perf_event.h> 26 #include <linux/ksm.h> 27 #include <asm/uaccess.h> 28 #include <asm/pgtable.h> 29 #include <asm/cacheflush.h> 30 #include <asm/tlbflush.h> 31 32 #ifndef pgprot_modify 33 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) 34 { 35 return newprot; 36 } 37 #endif 38 39 static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, 40 unsigned long addr, unsigned long end, pgprot_t newprot, 41 int dirty_accountable, int prot_numa) 42 { 43 struct mm_struct *mm = vma->vm_mm; 44 pte_t *pte, oldpte; 45 spinlock_t *ptl; 46 unsigned long pages = 0; 47 48 pte = pte_offset_map_lock(mm, pmd, addr, &ptl); 49 arch_enter_lazy_mmu_mode(); 50 do { 51 oldpte = *pte; 52 if (pte_present(oldpte)) { 53 pte_t ptent; 54 bool updated = false; 55 56 if (!prot_numa) { 57 ptent = ptep_modify_prot_start(mm, addr, pte); 58 if (pte_numa(ptent)) 59 ptent = pte_mknonnuma(ptent); 60 ptent = pte_modify(ptent, newprot); 61 updated = true; 62 } else { 63 struct page *page; 64 65 ptent = *pte; 66 page = vm_normal_page(vma, addr, oldpte); 67 if (page && !PageKsm(page)) { 68 if (!pte_numa(oldpte)) { 69 ptent = pte_mknuma(ptent); 70 set_pte_at(mm, addr, pte, ptent); 71 updated = true; 72 } 73 } 74 } 75 76 /* 77 * Avoid taking write faults for pages we know to be 78 * dirty. 79 */ 80 if (dirty_accountable && pte_dirty(ptent)) { 81 ptent = pte_mkwrite(ptent); 82 updated = true; 83 } 84 85 if (updated) 86 pages++; 87 88 /* Only !prot_numa always clears the pte */ 89 if (!prot_numa) 90 ptep_modify_prot_commit(mm, addr, pte, ptent); 91 } else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) { 92 swp_entry_t entry = pte_to_swp_entry(oldpte); 93 94 if (is_write_migration_entry(entry)) { 95 pte_t newpte; 96 /* 97 * A protection check is difficult so 98 * just be safe and disable write 99 */ 100 make_migration_entry_read(&entry); 101 newpte = swp_entry_to_pte(entry); 102 if (pte_swp_soft_dirty(oldpte)) 103 newpte = pte_swp_mksoft_dirty(newpte); 104 set_pte_at(mm, addr, pte, newpte); 105 106 pages++; 107 } 108 } 109 } while (pte++, addr += PAGE_SIZE, addr != end); 110 arch_leave_lazy_mmu_mode(); 111 pte_unmap_unlock(pte - 1, ptl); 112 113 return pages; 114 } 115 116 static inline unsigned long change_pmd_range(struct vm_area_struct *vma, 117 pud_t *pud, unsigned long addr, unsigned long end, 118 pgprot_t newprot, int dirty_accountable, int prot_numa) 119 { 120 pmd_t *pmd; 121 unsigned long next; 122 unsigned long pages = 0; 123 unsigned long nr_huge_updates = 0; 124 125 pmd = pmd_offset(pud, addr); 126 do { 127 unsigned long this_pages; 128 129 next = pmd_addr_end(addr, end); 130 if (pmd_trans_huge(*pmd)) { 131 if (next - addr != HPAGE_PMD_SIZE) 132 split_huge_page_pmd(vma, addr, pmd); 133 else { 134 int nr_ptes = change_huge_pmd(vma, pmd, addr, 135 newprot, prot_numa); 136 137 if (nr_ptes) { 138 if (nr_ptes == HPAGE_PMD_NR) { 139 pages += HPAGE_PMD_NR; 140 nr_huge_updates++; 141 } 142 continue; 143 } 144 } 145 /* fall through */ 146 } 147 if (pmd_none_or_clear_bad(pmd)) 148 continue; 149 this_pages = change_pte_range(vma, pmd, addr, next, newprot, 150 dirty_accountable, prot_numa); 151 pages += this_pages; 152 } while (pmd++, addr = next, addr != end); 153 154 if (nr_huge_updates) 155 count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates); 156 return pages; 157 } 158 159 static inline unsigned long change_pud_range(struct vm_area_struct *vma, 160 pgd_t *pgd, unsigned long addr, unsigned long end, 161 pgprot_t newprot, int dirty_accountable, int prot_numa) 162 { 163 pud_t *pud; 164 unsigned long next; 165 unsigned long pages = 0; 166 167 pud = pud_offset(pgd, addr); 168 do { 169 next = pud_addr_end(addr, end); 170 if (pud_none_or_clear_bad(pud)) 171 continue; 172 pages += change_pmd_range(vma, pud, addr, next, newprot, 173 dirty_accountable, prot_numa); 174 } while (pud++, addr = next, addr != end); 175 176 return pages; 177 } 178 179 static unsigned long change_protection_range(struct vm_area_struct *vma, 180 unsigned long addr, unsigned long end, pgprot_t newprot, 181 int dirty_accountable, int prot_numa) 182 { 183 struct mm_struct *mm = vma->vm_mm; 184 pgd_t *pgd; 185 unsigned long next; 186 unsigned long start = addr; 187 unsigned long pages = 0; 188 189 BUG_ON(addr >= end); 190 pgd = pgd_offset(mm, addr); 191 flush_cache_range(vma, addr, end); 192 set_tlb_flush_pending(mm); 193 do { 194 next = pgd_addr_end(addr, end); 195 if (pgd_none_or_clear_bad(pgd)) 196 continue; 197 pages += change_pud_range(vma, pgd, addr, next, newprot, 198 dirty_accountable, prot_numa); 199 } while (pgd++, addr = next, addr != end); 200 201 /* Only flush the TLB if we actually modified any entries: */ 202 if (pages) 203 flush_tlb_range(vma, start, end); 204 clear_tlb_flush_pending(mm); 205 206 return pages; 207 } 208 209 unsigned long change_protection(struct vm_area_struct *vma, unsigned long start, 210 unsigned long end, pgprot_t newprot, 211 int dirty_accountable, int prot_numa) 212 { 213 struct mm_struct *mm = vma->vm_mm; 214 unsigned long pages; 215 216 mmu_notifier_invalidate_range_start(mm, start, end); 217 if (is_vm_hugetlb_page(vma)) 218 pages = hugetlb_change_protection(vma, start, end, newprot); 219 else 220 pages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa); 221 mmu_notifier_invalidate_range_end(mm, start, end); 222 223 return pages; 224 } 225 226 int 227 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, 228 unsigned long start, unsigned long end, unsigned long newflags) 229 { 230 struct mm_struct *mm = vma->vm_mm; 231 unsigned long oldflags = vma->vm_flags; 232 long nrpages = (end - start) >> PAGE_SHIFT; 233 unsigned long charged = 0; 234 pgoff_t pgoff; 235 int error; 236 int dirty_accountable = 0; 237 238 if (newflags == oldflags) { 239 *pprev = vma; 240 return 0; 241 } 242 243 /* 244 * If we make a private mapping writable we increase our commit; 245 * but (without finer accounting) cannot reduce our commit if we 246 * make it unwritable again. hugetlb mapping were accounted for 247 * even if read-only so there is no need to account for them here 248 */ 249 if (newflags & VM_WRITE) { 250 if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| 251 VM_SHARED|VM_NORESERVE))) { 252 charged = nrpages; 253 if (security_vm_enough_memory_mm(mm, charged)) 254 return -ENOMEM; 255 newflags |= VM_ACCOUNT; 256 } 257 } 258 259 /* 260 * First try to merge with previous and/or next vma. 261 */ 262 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); 263 *pprev = vma_merge(mm, *pprev, start, end, newflags, 264 vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma)); 265 if (*pprev) { 266 vma = *pprev; 267 goto success; 268 } 269 270 *pprev = vma; 271 272 if (start != vma->vm_start) { 273 error = split_vma(mm, vma, start, 1); 274 if (error) 275 goto fail; 276 } 277 278 if (end != vma->vm_end) { 279 error = split_vma(mm, vma, end, 0); 280 if (error) 281 goto fail; 282 } 283 284 success: 285 /* 286 * vm_flags and vm_page_prot are protected by the mmap_sem 287 * held in write mode. 288 */ 289 vma->vm_flags = newflags; 290 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot, 291 vm_get_page_prot(newflags)); 292 293 if (vma_wants_writenotify(vma)) { 294 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); 295 dirty_accountable = 1; 296 } 297 298 change_protection(vma, start, end, vma->vm_page_prot, 299 dirty_accountable, 0); 300 301 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); 302 vm_stat_account(mm, newflags, vma->vm_file, nrpages); 303 perf_event_mmap(vma); 304 return 0; 305 306 fail: 307 vm_unacct_memory(charged); 308 return error; 309 } 310 311 SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, 312 unsigned long, prot) 313 { 314 unsigned long vm_flags, nstart, end, tmp, reqprot; 315 struct vm_area_struct *vma, *prev; 316 int error = -EINVAL; 317 const int grows = prot & (PROT_GROWSDOWN|PROT_GROWSUP); 318 prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP); 319 if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */ 320 return -EINVAL; 321 322 if (start & ~PAGE_MASK) 323 return -EINVAL; 324 if (!len) 325 return 0; 326 len = PAGE_ALIGN(len); 327 end = start + len; 328 if (end <= start) 329 return -ENOMEM; 330 if (!arch_validate_prot(prot)) 331 return -EINVAL; 332 333 reqprot = prot; 334 /* 335 * Does the application expect PROT_READ to imply PROT_EXEC: 336 */ 337 if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) 338 prot |= PROT_EXEC; 339 340 vm_flags = calc_vm_prot_bits(prot); 341 342 down_write(¤t->mm->mmap_sem); 343 344 vma = find_vma(current->mm, start); 345 error = -ENOMEM; 346 if (!vma) 347 goto out; 348 prev = vma->vm_prev; 349 if (unlikely(grows & PROT_GROWSDOWN)) { 350 if (vma->vm_start >= end) 351 goto out; 352 start = vma->vm_start; 353 error = -EINVAL; 354 if (!(vma->vm_flags & VM_GROWSDOWN)) 355 goto out; 356 } else { 357 if (vma->vm_start > start) 358 goto out; 359 if (unlikely(grows & PROT_GROWSUP)) { 360 end = vma->vm_end; 361 error = -EINVAL; 362 if (!(vma->vm_flags & VM_GROWSUP)) 363 goto out; 364 } 365 } 366 if (start > vma->vm_start) 367 prev = vma; 368 369 for (nstart = start ; ; ) { 370 unsigned long newflags; 371 372 /* Here we know that vma->vm_start <= nstart < vma->vm_end. */ 373 374 newflags = vm_flags; 375 newflags |= (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC)); 376 377 /* newflags >> 4 shift VM_MAY% in place of VM_% */ 378 if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) { 379 error = -EACCES; 380 goto out; 381 } 382 383 error = security_file_mprotect(vma, reqprot, prot); 384 if (error) 385 goto out; 386 387 tmp = vma->vm_end; 388 if (tmp > end) 389 tmp = end; 390 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); 391 if (error) 392 goto out; 393 nstart = tmp; 394 395 if (nstart < prev->vm_end) 396 nstart = prev->vm_end; 397 if (nstart >= end) 398 goto out; 399 400 vma = prev->vm_next; 401 if (!vma || vma->vm_start != nstart) { 402 error = -ENOMEM; 403 goto out; 404 } 405 } 406 out: 407 up_write(¤t->mm->mmap_sem); 408 return error; 409 } 410