| .. | .. |
|---|
| 22 | 22 | #include <linux/vmalloc.h> |
|---|
| 23 | 23 | #include <linux/highmem.h> |
|---|
| 24 | 24 | #include <linux/printk.h> |
|---|
| 25 | | -#include <linux/bootmem.h> |
|---|
| 25 | +#include <linux/memblock.h> |
|---|
| 26 | 26 | #include <linux/init.h> |
|---|
| 27 | 27 | #include <linux/slab.h> |
|---|
| 28 | 28 | #include <linux/uaccess.h> |
|---|
| .. | .. |
|---|
| 31 | 31 | #include <linux/ioport.h> |
|---|
| 32 | 32 | #include <linux/memory.h> |
|---|
| 33 | 33 | #include <linux/sched/task.h> |
|---|
| 34 | +#include <linux/security.h> |
|---|
| 34 | 35 | #include <asm/sections.h> |
|---|
| 35 | 36 | #include "internal.h" |
|---|
| 36 | 37 | |
|---|
| .. | .. |
|---|
| 192 | 193 | return 1; |
|---|
| 193 | 194 | |
|---|
| 194 | 195 | p = pfn_to_page(pfn); |
|---|
| 195 | | - if (!memmap_valid_within(pfn, p, page_zone(p))) |
|---|
| 196 | | - return 1; |
|---|
| 197 | 196 | |
|---|
| 198 | 197 | ent = kmalloc(sizeof(*ent), GFP_KERNEL); |
|---|
| 199 | 198 | if (!ent) |
|---|
| .. | .. |
|---|
| 511 | 510 | * Using bounce buffer to bypass the |
|---|
| 512 | 511 | * hardened user copy kernel text checks. |
|---|
| 513 | 512 | */ |
|---|
| 514 | | - if (probe_kernel_read(buf, (void *) start, tsz)) { |
|---|
| 513 | + if (copy_from_kernel_nofault(buf, (void *)start, |
|---|
| 514 | + tsz)) { |
|---|
| 515 | 515 | if (clear_user(buffer, tsz)) { |
|---|
| 516 | 516 | ret = -EFAULT; |
|---|
| 517 | 517 | goto out; |
|---|
| .. | .. |
|---|
| 545 | 545 | |
|---|
| 546 | 546 | static int open_kcore(struct inode *inode, struct file *filp) |
|---|
| 547 | 547 | { |
|---|
| 548 | + int ret = security_locked_down(LOCKDOWN_KCORE); |
|---|
| 549 | + |
|---|
| 548 | 550 | if (!capable(CAP_SYS_RAWIO)) |
|---|
| 549 | 551 | return -EPERM; |
|---|
| 552 | + |
|---|
| 553 | + if (ret) |
|---|
| 554 | + return ret; |
|---|
| 550 | 555 | |
|---|
| 551 | 556 | filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); |
|---|
| 552 | 557 | if (!filp->private_data) |
|---|
| .. | .. |
|---|
| 568 | 573 | return 0; |
|---|
| 569 | 574 | } |
|---|
| 570 | 575 | |
|---|
| 571 | | -static const struct file_operations proc_kcore_operations = { |
|---|
| 572 | | - .read = read_kcore, |
|---|
| 573 | | - .open = open_kcore, |
|---|
| 574 | | - .release = release_kcore, |
|---|
| 575 | | - .llseek = default_llseek, |
|---|
| 576 | +static const struct proc_ops kcore_proc_ops = { |
|---|
| 577 | + .proc_read = read_kcore, |
|---|
| 578 | + .proc_open = open_kcore, |
|---|
| 579 | + .proc_release = release_kcore, |
|---|
| 580 | + .proc_lseek = default_llseek, |
|---|
| 576 | 581 | }; |
|---|
| 577 | 582 | |
|---|
| 578 | 583 | /* just remember that we have to update kcore */ |
|---|
| .. | .. |
|---|
| 615 | 620 | /* |
|---|
| 616 | 621 | * MODULES_VADDR has no intersection with VMALLOC_ADDR. |
|---|
| 617 | 622 | */ |
|---|
| 618 | | -struct kcore_list kcore_modules; |
|---|
| 623 | +static struct kcore_list kcore_modules; |
|---|
| 619 | 624 | static void __init add_modules_range(void) |
|---|
| 620 | 625 | { |
|---|
| 621 | 626 | if (MODULES_VADDR != VMALLOC_START && MODULES_END != VMALLOC_END) { |
|---|
| .. | .. |
|---|
| 631 | 636 | |
|---|
| 632 | 637 | static int __init proc_kcore_init(void) |
|---|
| 633 | 638 | { |
|---|
| 634 | | - proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, |
|---|
| 635 | | - &proc_kcore_operations); |
|---|
| 639 | + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &kcore_proc_ops); |
|---|
| 636 | 640 | if (!proc_root_kcore) { |
|---|
| 637 | 641 | pr_err("couldn't create /proc/kcore\n"); |
|---|
| 638 | 642 | return 0; /* Always returns 0. */ |
|---|