Skip to content

Commit

Permalink
Merge branch 'akpm' (patches from Andrew)
Browse files Browse the repository at this point in the history
Merge misc fixes from Andrew Morton:
 "18 patches.

  Subsystems affected by this patch series: mm (pagealloc, memcg, kasan,
  memory-failure, and highmem), ubsan, proc, and MAINTAINERS"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  MAINTAINERS: add a couple more files to the Clang/LLVM section
  proc_sysctl: fix oops caused by incorrect command parameters
  powerpc/mm/highmem: use __set_pte_at() for kmap_local()
  mips/mm/highmem: use set_pte() for kmap_local()
  mm/highmem: prepare for overriding set_pte_at()
  sparc/mm/highmem: flush cache and TLB
  mm: fix page reference leak in soft_offline_page()
  ubsan: disable unsigned-overflow check for i386
  kasan, mm: fix resetting page_alloc tags for HW_TAGS
  kasan, mm: fix conflicts with init_on_alloc/free
  kasan: fix HW_TAGS boot parameters
  kasan: fix incorrect arguments passing in kasan_add_zero_shadow
  kasan: fix unaligned address is unhandled in kasan_remove_zero_shadow
  mm: fix numa stats for thp migration
  mm: memcg: fix memcg file_dirty numa stat
  mm: memcg/slab: optimize objcg stock draining
  mm: fix initialization of struct page for holes in memory layout
  x86/setup: don't remove E820_TYPE_RAM for pfn 0
  • Loading branch information
Linus Torvalds committed Jan 24, 2021
2 parents fdbc80b + e82d891 commit 5130680
Show file tree
Hide file tree
Showing 16 changed files with 168 additions and 148 deletions.
27 changes: 6 additions & 21 deletions Documentation/dev-tools/kasan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,29 +160,14 @@ intended for use in production as a security mitigation. Therefore it supports
boot parameters that allow to disable KASAN competely or otherwise control
particular KASAN features.

The things that can be controlled are:
- ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).

1. Whether KASAN is enabled at all.
2. Whether KASAN collects and saves alloc/free stacks.
3. Whether KASAN panics on a detected bug or not.
- ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
traces collection (default: ``on`` for ``CONFIG_DEBUG_KERNEL=y``, otherwise
``off``).

The ``kasan.mode`` boot parameter allows to choose one of three main modes:

- ``kasan.mode=off`` - KASAN is disabled, no tag checks are performed
- ``kasan.mode=prod`` - only essential production features are enabled
- ``kasan.mode=full`` - all KASAN features are enabled

The chosen mode provides default control values for the features mentioned
above. However it's also possible to override the default values by providing:

- ``kasan.stacktrace=off`` or ``=on`` - enable alloc/free stack collection
(default: ``on`` for ``mode=full``,
otherwise ``off``)
- ``kasan.fault=report`` or ``=panic`` - only print KASAN report or also panic
(default: ``report``)

If ``kasan.mode`` parameter is not provided, it defaults to ``full`` when
``CONFIG_DEBUG_KERNEL`` is enabled, and to ``prod`` otherwise.
- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
report or also panic the kernel (default: ``report``).

For developers
~~~~~~~~~~~~~~
Expand Down
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4311,7 +4311,9 @@ W: https://clangbuiltlinux.github.io/
B: https://github.com/ClangBuiltLinux/linux/issues
C: irc://chat.freenode.net/clangbuiltlinux
F: Documentation/kbuild/llvm.rst
F: include/linux/compiler-clang.h
F: scripts/clang-tools/
F: scripts/clang-version.sh
F: scripts/lld-version.sh
K: \b(?i:clang|llvm)\b

Expand Down
1 change: 1 addition & 0 deletions arch/mips/include/asm/highmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ extern void kmap_flush_tlb(unsigned long addr);

#define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases)

#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) set_pte(ptep, ptev)
#define arch_kmap_local_post_map(vaddr, pteval) local_flush_tlb_one(vaddr)
#define arch_kmap_local_post_unmap(vaddr) local_flush_tlb_one(vaddr)

Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/highmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ extern pte_t *pkmap_page_table;

#define flush_cache_kmaps() flush_cache_all()

#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \
__set_pte_at(mm, vaddr, ptep, ptev, 1)
#define arch_kmap_local_post_map(vaddr, pteval) \
local_flush_tlb_page(NULL, vaddr)
#define arch_kmap_local_post_unmap(vaddr) \
Expand Down
9 changes: 5 additions & 4 deletions arch/sparc/include/asm/highmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ extern pte_t *pkmap_page_table;

#define flush_cache_kmaps() flush_cache_all()

/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */
#define arch_kmap_local_post_map(vaddr, pteval) flush_cache_all()
#define arch_kmap_local_post_unmap(vaddr) flush_cache_all()

/* FIXME: Use __flush_*_one(vaddr) instead of flush_*_all() -- Anton */
#define arch_kmap_local_pre_map(vaddr, pteval) flush_cache_all()
#define arch_kmap_local_pre_unmap(vaddr) flush_cache_all()
#define arch_kmap_local_post_map(vaddr, pteval) flush_tlb_all()
#define arch_kmap_local_post_unmap(vaddr) flush_tlb_all()

#endif /* __KERNEL__ */

Expand Down
20 changes: 9 additions & 11 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,17 +660,6 @@ static void __init trim_platform_memory_ranges(void)

static void __init trim_bios_range(void)
{
/*
* A special case is the first 4Kb of memory;
* This is a BIOS owned area, not kernel ram, but generally
* not listed as such in the E820 table.
*
* This typically reserves additional memory (64KiB by default)
* since some BIOSes are known to corrupt low memory. See the
* Kconfig help text for X86_RESERVE_LOW.
*/
e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);

/*
* special case: Some BIOSes report the PC BIOS
* area (640Kb -> 1Mb) as RAM even though it is not.
Expand Down Expand Up @@ -728,6 +717,15 @@ early_param("reservelow", parse_reservelow);

static void __init trim_low_memory_range(void)
{
/*
* A special case is the first 4Kb of memory;
* This is a BIOS owned area, not kernel ram, but generally
* not listed as such in the E820 table.
*
* This typically reserves additional memory (64KiB by default)
* since some BIOSes are known to corrupt low memory. See the
* Kconfig help text for X86_RESERVE_LOW.
*/
memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE));
}

Expand Down
7 changes: 6 additions & 1 deletion fs/proc/proc_sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,12 @@ static int process_sysctl_arg(char *param, char *val,
return 0;
}

if (!val)
return -EINVAL;
len = strlen(val);
if (len == 0)
return -EINVAL;

/*
* To set sysctl options, we use a temporary mount of proc, look up the
* respective sys/ file and write to it. To avoid mounting it when no
Expand Down Expand Up @@ -1811,7 +1817,6 @@ static int process_sysctl_arg(char *param, char *val,
file, param, val);
goto out;
}
len = strlen(val);
wret = kernel_write(file, val, len, &pos);
if (wret < 0) {
err = wret;
Expand Down
1 change: 1 addition & 0 deletions lib/Kconfig.ubsan
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ config UBSAN_SIGNED_OVERFLOW
config UBSAN_UNSIGNED_OVERFLOW
bool "Perform checking for unsigned arithmetic overflow"
depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
depends on !X86_32 # avoid excessive stack usage on x86-32/clang
help
This option enables -fsanitize=unsigned-integer-overflow which checks
for overflow of any arithmetic operations with unsigned integers. This
Expand Down
7 changes: 6 additions & 1 deletion mm/highmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ static inline void *arch_kmap_local_high_get(struct page *page)
}
#endif

#ifndef arch_kmap_local_set_pte
#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \
set_pte_at(mm, vaddr, ptep, ptev)
#endif

/* Unmap a local mapping which was obtained by kmap_high_get() */
static inline bool kmap_high_unmap_local(unsigned long vaddr)
{
Expand Down Expand Up @@ -515,7 +520,7 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
BUG_ON(!pte_none(*(kmap_pte - idx)));
pteval = pfn_pte(pfn, prot);
set_pte_at(&init_mm, vaddr, kmap_pte - idx, pteval);
arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte - idx, pteval);
arch_kmap_local_post_map(vaddr, pteval);
current->kmap_ctrl.pteval[kmap_local_idx()] = pteval;
preempt_enable();
Expand Down
77 changes: 32 additions & 45 deletions mm/kasan/hw_tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@

#include "kasan.h"

enum kasan_arg_mode {
KASAN_ARG_MODE_DEFAULT,
KASAN_ARG_MODE_OFF,
KASAN_ARG_MODE_PROD,
KASAN_ARG_MODE_FULL,
enum kasan_arg {
KASAN_ARG_DEFAULT,
KASAN_ARG_OFF,
KASAN_ARG_ON,
};

enum kasan_arg_stacktrace {
Expand All @@ -38,7 +37,7 @@ enum kasan_arg_fault {
KASAN_ARG_FAULT_PANIC,
};

static enum kasan_arg_mode kasan_arg_mode __ro_after_init;
static enum kasan_arg kasan_arg __ro_after_init;
static enum kasan_arg_stacktrace kasan_arg_stacktrace __ro_after_init;
static enum kasan_arg_fault kasan_arg_fault __ro_after_init;

Expand All @@ -52,26 +51,24 @@ DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
/* Whether panic or disable tag checking on fault. */
bool kasan_flag_panic __ro_after_init;

/* kasan.mode=off/prod/full */
static int __init early_kasan_mode(char *arg)
/* kasan=off/on */
static int __init early_kasan_flag(char *arg)
{
if (!arg)
return -EINVAL;

if (!strcmp(arg, "off"))
kasan_arg_mode = KASAN_ARG_MODE_OFF;
else if (!strcmp(arg, "prod"))
kasan_arg_mode = KASAN_ARG_MODE_PROD;
else if (!strcmp(arg, "full"))
kasan_arg_mode = KASAN_ARG_MODE_FULL;
kasan_arg = KASAN_ARG_OFF;
else if (!strcmp(arg, "on"))
kasan_arg = KASAN_ARG_ON;
else
return -EINVAL;

return 0;
}
early_param("kasan.mode", early_kasan_mode);
early_param("kasan", early_kasan_flag);

/* kasan.stack=off/on */
/* kasan.stacktrace=off/on */
static int __init early_kasan_flag_stacktrace(char *arg)
{
if (!arg)
Expand Down Expand Up @@ -113,8 +110,8 @@ void kasan_init_hw_tags_cpu(void)
* as this function is only called for MTE-capable hardware.
*/

/* If KASAN is disabled, do nothing. */
if (kasan_arg_mode == KASAN_ARG_MODE_OFF)
/* If KASAN is disabled via command line, don't initialize it. */
if (kasan_arg == KASAN_ARG_OFF)
return;

hw_init_tags(KASAN_TAG_MAX);
Expand All @@ -124,43 +121,28 @@ void kasan_init_hw_tags_cpu(void)
/* kasan_init_hw_tags() is called once on boot CPU. */
void __init kasan_init_hw_tags(void)
{
/* If hardware doesn't support MTE, do nothing. */
/* If hardware doesn't support MTE, don't initialize KASAN. */
if (!system_supports_mte())
return;

/* Choose KASAN mode if kasan boot parameter is not provided. */
if (kasan_arg_mode == KASAN_ARG_MODE_DEFAULT) {
if (IS_ENABLED(CONFIG_DEBUG_KERNEL))
kasan_arg_mode = KASAN_ARG_MODE_FULL;
else
kasan_arg_mode = KASAN_ARG_MODE_PROD;
}

/* Preset parameter values based on the mode. */
switch (kasan_arg_mode) {
case KASAN_ARG_MODE_DEFAULT:
/* Shouldn't happen as per the check above. */
WARN_ON(1);
return;
case KASAN_ARG_MODE_OFF:
/* If KASAN is disabled, do nothing. */
/* If KASAN is disabled via command line, don't initialize it. */
if (kasan_arg == KASAN_ARG_OFF)
return;
case KASAN_ARG_MODE_PROD:
static_branch_enable(&kasan_flag_enabled);
break;
case KASAN_ARG_MODE_FULL:
static_branch_enable(&kasan_flag_enabled);
static_branch_enable(&kasan_flag_stacktrace);
break;
}

/* Now, optionally override the presets. */
/* Enable KASAN. */
static_branch_enable(&kasan_flag_enabled);

switch (kasan_arg_stacktrace) {
case KASAN_ARG_STACKTRACE_DEFAULT:
/*
* Default to enabling stack trace collection for
* debug kernels.
*/
if (IS_ENABLED(CONFIG_DEBUG_KERNEL))
static_branch_enable(&kasan_flag_stacktrace);
break;
case KASAN_ARG_STACKTRACE_OFF:
static_branch_disable(&kasan_flag_stacktrace);
/* Do nothing, kasan_flag_stacktrace keeps its default value. */
break;
case KASAN_ARG_STACKTRACE_ON:
static_branch_enable(&kasan_flag_stacktrace);
Expand All @@ -169,11 +151,16 @@ void __init kasan_init_hw_tags(void)

switch (kasan_arg_fault) {
case KASAN_ARG_FAULT_DEFAULT:
/*
* Default to no panic on report.
* Do nothing, kasan_flag_panic keeps its default value.
*/
break;
case KASAN_ARG_FAULT_REPORT:
kasan_flag_panic = false;
/* Do nothing, kasan_flag_panic keeps its default value. */
break;
case KASAN_ARG_FAULT_PANIC:
/* Enable panic on report. */
kasan_flag_panic = true;
break;
}
Expand Down
23 changes: 13 additions & 10 deletions mm/kasan/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,10 @@ static void kasan_remove_pmd_table(pmd_t *pmd, unsigned long addr,

if (kasan_pte_table(*pmd)) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE))
IS_ALIGNED(next, PMD_SIZE)) {
pmd_clear(pmd);
continue;
continue;
}
}
pte = pte_offset_kernel(pmd, addr);
kasan_remove_pte_table(pte, addr, next);
Expand All @@ -398,9 +399,10 @@ static void kasan_remove_pud_table(pud_t *pud, unsigned long addr,

if (kasan_pmd_table(*pud)) {
if (IS_ALIGNED(addr, PUD_SIZE) &&
IS_ALIGNED(next, PUD_SIZE))
IS_ALIGNED(next, PUD_SIZE)) {
pud_clear(pud);
continue;
continue;
}
}
pmd = pmd_offset(pud, addr);
pmd_base = pmd_offset(pud, 0);
Expand All @@ -424,9 +426,10 @@ static void kasan_remove_p4d_table(p4d_t *p4d, unsigned long addr,

if (kasan_pud_table(*p4d)) {
if (IS_ALIGNED(addr, P4D_SIZE) &&
IS_ALIGNED(next, P4D_SIZE))
IS_ALIGNED(next, P4D_SIZE)) {
p4d_clear(p4d);
continue;
continue;
}
}
pud = pud_offset(p4d, addr);
kasan_remove_pud_table(pud, addr, next);
Expand Down Expand Up @@ -457,9 +460,10 @@ void kasan_remove_zero_shadow(void *start, unsigned long size)

if (kasan_p4d_table(*pgd)) {
if (IS_ALIGNED(addr, PGDIR_SIZE) &&
IS_ALIGNED(next, PGDIR_SIZE))
IS_ALIGNED(next, PGDIR_SIZE)) {
pgd_clear(pgd);
continue;
continue;
}
}

p4d = p4d_offset(pgd, addr);
Expand All @@ -482,7 +486,6 @@ int kasan_add_zero_shadow(void *start, unsigned long size)

ret = kasan_populate_early_shadow(shadow_start, shadow_end);
if (ret)
kasan_remove_zero_shadow(shadow_start,
size >> KASAN_SHADOW_SCALE_SHIFT);
kasan_remove_zero_shadow(start, size);
return ret;
}
4 changes: 1 addition & 3 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -3115,9 +3115,7 @@ void __memcg_kmem_uncharge(struct mem_cgroup *memcg, unsigned int nr_pages)
if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
page_counter_uncharge(&memcg->kmem, nr_pages);

page_counter_uncharge(&memcg->memory, nr_pages);
if (do_memsw_account())
page_counter_uncharge(&memcg->memsw, nr_pages);
refill_stock(memcg, nr_pages);
}

/**
Expand Down
Loading

0 comments on commit 5130680

Please sign in to comment.