From: Ravi Kumar Reddy <bnrkreddy@xxxxxxxxxxx> - WARNING: Missing a blank line after declarations - WARNING: Use #include <linux/cacheflush.h> instead of <asm/cacheflush.h> - WARNING: externs should be avoided in .c files extern void mt_dump(const struct maple_tree *mt); - WARNING: braces {} are not necessary for single statement blocks - WARNING: Block comments use a trailing */ on a separate line - WARNING: function definition argument 'struct file *' should also have an identifier - WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable - WARNING: simple_strtoul is obsolete, use kstrtoul instead - WARNING: Comparisons should place the constant on the right side of the test Testing: kernel cmdline included with: stack_guard_gap=-1 kernel log: [ 0.018025] mmap: Invalid page count '-1' for stack gap protection Signed-off-by: Ravi Kumar Reddy <bnrkreddy@xxxxxxxxxxx> --- mm/mmap.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 87d929316d57..5d4b0d625607 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -48,9 +48,9 @@ #include <linux/sched/mm.h> #include <linux/uaccess.h> -#include <asm/cacheflush.h> +#include <linux/cacheflush.h> #include <asm/tlb.h> -#include <asm/mmu_context.h> +#include <linux/mmu_context.h> #define CREATE_TRACE_POINTS #include <trace/events/mmap.h> @@ -124,6 +124,7 @@ void unlink_file_vma(struct vm_area_struct *vma) if (file) { struct address_space *mapping = file->f_mapping; + i_mmap_lock_write(mapping); __remove_shared_vm_struct(vma, file, mapping); i_mmap_unlock_write(mapping); @@ -281,9 +282,6 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) } #if defined(CONFIG_DEBUG_VM_MAPLE_TREE) -extern void mt_validate(struct maple_tree *mt); -extern void mt_dump(const struct maple_tree *mt); - /* Validate the maple tree */ static void validate_mm_mt(struct mm_struct *mm) { @@ -572,9 +570,8 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma, } /* Expanding over the next vma */ - if (remove_next && file) { + if (remove_next && file) __remove_shared_vm_struct(next, file, mapping); - } if (anon_vma) { anon_vma_interval_tree_post_update_vma(vma); @@ -946,6 +943,7 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) && is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { pgoff_t vm_pglen; + vm_pglen = vma_pages(vma); if (vma->vm_pgoff + vm_pglen == vm_pgoff) return 1; @@ -1511,8 +1509,10 @@ int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) if (vm_ops && (vm_ops->page_mkwrite || vm_ops->pfn_mkwrite)) return 1; - /* The open routine did something to the protections that pgprot_modify - * won't preserve? */ + /* + * The open routine did something to the protections that pgprot_modify + * won't preserve? + */ if (pgprot_val(vm_page_prot) != pgprot_val(vm_pgprot_modify(vm_page_prot, vm_flags))) return 0; @@ -1755,10 +1755,12 @@ unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { - unsigned long (*get_area)(struct file *, unsigned long, - unsigned long, unsigned long, unsigned long); + unsigned long (*get_area)(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags); unsigned long error = arch_mmap_check(addr, len, flags); + if (error) return error; @@ -1792,7 +1794,6 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, error = security_mmap_addr(addr); return error ? error : addr; } - EXPORT_SYMBOL(get_unmapped_area); /** @@ -2079,11 +2080,16 @@ unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT; static int __init cmdline_parse_stack_guard_gap(char *p) { unsigned long val; - char *endptr; + int ret; + + ret = kstrtoul(p, 10, &val); + if (ret) { + pr_warn("Invalid page count '%s' for stack gap protection\n", + p); + return 1; + } - val = simple_strtoul(p, &endptr, 10); - if (!*endptr) - stack_guard_gap = val << PAGE_SHIFT; + stack_guard_gap = val << PAGE_SHIFT; return 1; } @@ -2138,7 +2144,6 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) return vma; } #endif - EXPORT_SYMBOL_GPL(find_extend_vma); /* @@ -2196,6 +2201,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, { struct vm_area_struct *new; int err; + validate_mm_mt(mm); if (vma->vm_ops && vma->vm_ops->may_split) { @@ -3365,6 +3371,7 @@ static vm_fault_t special_mapping_fault(struct vm_fault *vmf) if (*pages) { struct page *page = *pages; + get_page(page); vmf->page = page; return 0; @@ -3714,12 +3721,12 @@ static int reserve_mem_notifier(struct notifier_block *nb, case MEM_ONLINE: /* Default max is 128MB. Leave alone if modified by operator. */ tmp = sysctl_user_reserve_kbytes; - if (0 < tmp && tmp < (1UL << 17)) + if (tmp > 0 && tmp < (1UL << 17)) init_user_reserve(); /* Default max is 8MB. Leave alone if modified by operator. */ tmp = sysctl_admin_reserve_kbytes; - if (0 < tmp && tmp < (1UL << 13)) + if (tmp > 0 && tmp < (1UL << 13)) init_admin_reserve(); break; -- 2.31.1