diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 3 | ||||
-rw-r--r-- | lib/Kconfig.debug | 10 | ||||
-rw-r--r-- | lib/Kconfig.kasan | 65 | ||||
-rw-r--r-- | lib/Kconfig.ubsan | 1 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/devmem_is_allowed.c | 27 | ||||
-rw-r--r-- | lib/fonts/font_ter16x32.c | 6 | ||||
-rw-r--r-- | lib/genalloc.c | 25 | ||||
-rw-r--r-- | lib/iov_iter.c | 2 | ||||
-rw-r--r-- | lib/raid6/Makefile | 2 | ||||
-rw-r--r-- | lib/test_kasan.c | 2 | ||||
-rw-r--r-- | lib/test_kasan_module.c | 2 | ||||
-rw-r--r-- | lib/zlib_dfltcc/Makefile | 2 | ||||
-rw-r--r-- | lib/zlib_dfltcc/dfltcc.c | 6 | ||||
-rw-r--r-- | lib/zlib_dfltcc/dfltcc_deflate.c | 3 | ||||
-rw-r--r-- | lib/zlib_dfltcc/dfltcc_inflate.c | 4 | ||||
-rw-r--r-- | lib/zlib_dfltcc/dfltcc_syms.c | 17 |
17 files changed, 109 insertions, 70 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index b46a9fd122c8..46806332a8cc 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -686,6 +686,9 @@ config GENERIC_LIB_CMPDI2 config GENERIC_LIB_UCMPDI2 bool +config GENERIC_LIB_DEVMEM_IS_ALLOWED + bool + config PLDMFW bool default n diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 7d7097c5dc58..7937265ef879 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -295,14 +295,6 @@ config GDB_SCRIPTS endif # DEBUG_INFO -config ENABLE_MUST_CHECK - bool "Enable __must_check logic" - default y - help - Enable the __must_check logic in the kernel build. Disable this to - suppress the "warning: ignoring return value of 'foo', declared with - attribute warn_unused_result" messages. - config FRAME_WARN int "Warn for stack frames larger than" range 0 8192 @@ -1676,7 +1668,7 @@ config ARCH_HAS_DEVMEM_IS_ALLOWED config STRICT_DEVMEM bool "Filter access to /dev/mem" depends on MMU && DEVMEM - depends on ARCH_HAS_DEVMEM_IS_ALLOWED + depends on ARCH_HAS_DEVMEM_IS_ALLOWED || GENERIC_LIB_DEVMEM_IS_ALLOWED default y if PPC || X86 || ARM64 help If this option is disabled, you allow userspace (root) access to all diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index 8fb097057fec..f5fa4ba126bf 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -6,7 +6,10 @@ config HAVE_ARCH_KASAN config HAVE_ARCH_KASAN_SW_TAGS bool -config HAVE_ARCH_KASAN_VMALLOC +config HAVE_ARCH_KASAN_HW_TAGS + bool + +config HAVE_ARCH_KASAN_VMALLOC bool config CC_HAS_KASAN_GENERIC @@ -15,15 +18,20 @@ config CC_HAS_KASAN_GENERIC config CC_HAS_KASAN_SW_TAGS def_bool $(cc-option, -fsanitize=kernel-hwaddress) +# This option is only required for software KASAN modes. +# Old GCC versions don't have proper support for no_sanitize_address. +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89124 for details. config CC_HAS_WORKING_NOSANITIZE_ADDRESS def_bool !CC_IS_GCC || GCC_VERSION >= 80300 menuconfig KASAN bool "KASAN: runtime memory debugger" - depends on (HAVE_ARCH_KASAN && CC_HAS_KASAN_GENERIC) || \ - (HAVE_ARCH_KASAN_SW_TAGS && CC_HAS_KASAN_SW_TAGS) + depends on (((HAVE_ARCH_KASAN && CC_HAS_KASAN_GENERIC) || \ + (HAVE_ARCH_KASAN_SW_TAGS && CC_HAS_KASAN_SW_TAGS)) && \ + CC_HAS_WORKING_NOSANITIZE_ADDRESS) || \ + HAVE_ARCH_KASAN_HW_TAGS depends on (SLUB && SYSFS) || (SLAB && !DEBUG_SLAB) - depends on CC_HAS_WORKING_NOSANITIZE_ADDRESS + select STACKDEPOT help Enables KASAN (KernelAddressSANitizer) - runtime memory debugger, designed to find out-of-bounds accesses and use-after-free bugs. @@ -35,21 +43,24 @@ choice prompt "KASAN mode" default KASAN_GENERIC help - KASAN has two modes: generic KASAN (similar to userspace ASan, - x86_64/arm64/xtensa, enabled with CONFIG_KASAN_GENERIC) and - software tag-based KASAN (a version based on software memory - tagging, arm64 only, similar to userspace HWASan, enabled with - CONFIG_KASAN_SW_TAGS). + KASAN has three modes: + 1. generic KASAN (similar to userspace ASan, + x86_64/arm64/xtensa, enabled with CONFIG_KASAN_GENERIC), + 2. software tag-based KASAN (arm64 only, based on software + memory tagging (similar to userspace HWASan), enabled with + CONFIG_KASAN_SW_TAGS), and + 3. hardware tag-based KASAN (arm64 only, based on hardware + memory tagging, enabled with CONFIG_KASAN_HW_TAGS). + + All KASAN modes are strictly debugging features. - Both generic and tag-based KASAN are strictly debugging features. + For better error reports enable CONFIG_STACKTRACE. config KASAN_GENERIC bool "Generic mode" depends on HAVE_ARCH_KASAN && CC_HAS_KASAN_GENERIC - depends on (SLUB && SYSFS) || (SLAB && !DEBUG_SLAB) select SLUB_DEBUG if SLUB select CONSTRUCTORS - select STACKDEPOT help Enables generic KASAN mode. @@ -62,23 +73,22 @@ config KASAN_GENERIC and introduces an overhead of ~x1.5 for the rest of the allocations. The performance slowdown is ~x3. - For better error detection enable CONFIG_STACKTRACE. - Currently CONFIG_KASAN_GENERIC doesn't work with CONFIG_DEBUG_SLAB (the resulting kernel does not boot). config KASAN_SW_TAGS bool "Software tag-based mode" depends on HAVE_ARCH_KASAN_SW_TAGS && CC_HAS_KASAN_SW_TAGS - depends on (SLUB && SYSFS) || (SLAB && !DEBUG_SLAB) select SLUB_DEBUG if SLUB select CONSTRUCTORS - select STACKDEPOT help Enables software tag-based KASAN mode. - This mode requires Top Byte Ignore support by the CPU and therefore - is only supported for arm64. This mode requires Clang. + This mode require software memory tagging support in the form of + HWASan-like compiler instrumentation. + + Currently this mode is only implemented for arm64 CPUs and relies on + Top Byte Ignore. This mode requires Clang. This mode consumes about 1/16th of available memory at kernel start and introduces an overhead of ~20% for the rest of the allocations. @@ -86,15 +96,27 @@ config KASAN_SW_TAGS casting and comparison, as it embeds tags into the top byte of each pointer. - For better error detection enable CONFIG_STACKTRACE. - Currently CONFIG_KASAN_SW_TAGS doesn't work with CONFIG_DEBUG_SLAB (the resulting kernel does not boot). +config KASAN_HW_TAGS + bool "Hardware tag-based mode" + depends on HAVE_ARCH_KASAN_HW_TAGS + depends on SLUB + help + Enables hardware tag-based KASAN mode. + + This mode requires hardware memory tagging support, and can be used + by any architecture that provides it. + + Currently this mode is only implemented for arm64 CPUs starting from + ARMv8.5 and relies on Memory Tagging Extension and Top Byte Ignore. + endchoice choice prompt "Instrumentation type" + depends on KASAN_GENERIC || KASAN_SW_TAGS default KASAN_OUTLINE config KASAN_OUTLINE @@ -118,6 +140,7 @@ endchoice config KASAN_STACK_ENABLE bool "Enable stack instrumentation (unsafe)" if CC_IS_CLANG && !COMPILE_TEST + depends on KASAN_GENERIC || KASAN_SW_TAGS help The LLVM stack address sanitizer has a know problem that causes excessive stack usage in a lot of functions, see @@ -146,7 +169,7 @@ config KASAN_SW_TAGS_IDENTIFY config KASAN_VMALLOC bool "Back mappings in vmalloc space with real shadow memory" - depends on HAVE_ARCH_KASAN_VMALLOC + depends on KASAN_GENERIC && HAVE_ARCH_KASAN_VMALLOC help By default, the shadow region for vmalloc space is the read-only zero page. This means that KASAN cannot detect errors involving diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan index 8b635fd75fe4..3a0b1c930733 100644 --- a/lib/Kconfig.ubsan +++ b/lib/Kconfig.ubsan @@ -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 diff --git a/lib/Makefile b/lib/Makefile index 8598e8796edf..afeff05fa8c5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -354,3 +354,5 @@ obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o obj-$(CONFIG_BITS_TEST) += test_bits.o obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o + +obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o diff --git a/lib/devmem_is_allowed.c b/lib/devmem_is_allowed.c new file mode 100644 index 000000000000..c0d67c541849 --- /dev/null +++ b/lib/devmem_is_allowed.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * A generic version of devmem_is_allowed. + * + * Based on arch/arm64/mm/mmap.c + * + * Copyright (C) 2020 Google, Inc. + * Copyright (C) 2012 ARM Ltd. + */ + +#include <linux/mm.h> +#include <linux/ioport.h> + +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. We mimic x86 here by + * disallowing access to system RAM as well as device-exclusive MMIO regions. + * This effectively disable read()/write() on /dev/mem. + */ +int devmem_is_allowed(unsigned long pfn) +{ + if (iomem_is_exclusive(pfn << PAGE_SHIFT)) + return 0; + if (!page_is_ram(pfn)) + return 1; + return 0; +} diff --git a/lib/fonts/font_ter16x32.c b/lib/fonts/font_ter16x32.c index 1955d624177c..5baedc573dd6 100644 --- a/lib/fonts/font_ter16x32.c +++ b/lib/fonts/font_ter16x32.c @@ -774,8 +774,8 @@ static const struct font_data fontdata_ter16x32 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 95 */ - 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x00, - 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, + 0x07, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1169,7 +1169,7 @@ static const struct font_data fontdata_ter16x32 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xf8, 0x7f, 0xfc, 0x03, 0x9e, 0x03, 0x8e, + 0x7e, 0xf8, 0x7f, 0xfc, 0x03, 0x9e, 0x03, 0x8e, 0x03, 0x8e, 0x3f, 0x8e, 0x7f, 0xfe, 0xf3, 0xfe, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xf3, 0xce, 0x7f, 0xfe, 0x3e, 0xfc, 0x00, 0x00, 0x00, 0x00, diff --git a/lib/genalloc.c b/lib/genalloc.c index 7f1244b5294a..dab97bb69df6 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -81,14 +81,14 @@ static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear) * users set the same bit, one user will return remain bits, otherwise * return 0. */ -static int bitmap_set_ll(unsigned long *map, int start, int nr) +static int bitmap_set_ll(unsigned long *map, unsigned long start, unsigned long nr) { unsigned long *p = map + BIT_WORD(start); - const int size = start + nr; + const unsigned long size = start + nr; int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); - while (nr - bits_to_set >= 0) { + while (nr >= bits_to_set) { if (set_bits_ll(p, mask_to_set)) return nr; nr -= bits_to_set; @@ -116,14 +116,15 @@ static int bitmap_set_ll(unsigned long *map, int start, int nr) * users clear the same bit, one user will return remain bits, * otherwise return 0. */ -static int bitmap_clear_ll(unsigned long *map, int start, int nr) +static unsigned long +bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr) { unsigned long *p = map + BIT_WORD(start); - const int size = start + nr; + const unsigned long size = start + nr; int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); - while (nr - bits_to_clear >= 0) { + while (nr >= bits_to_clear) { if (clear_bits_ll(p, mask_to_clear)) return nr; nr -= bits_to_clear; @@ -183,8 +184,8 @@ int gen_pool_add_owner(struct gen_pool *pool, unsigned long virt, phys_addr_t ph size_t size, int nid, void *owner) { struct gen_pool_chunk *chunk; - int nbits = size >> pool->min_alloc_order; - int nbytes = sizeof(struct gen_pool_chunk) + + unsigned long nbits = size >> pool->min_alloc_order; + unsigned long nbytes = sizeof(struct gen_pool_chunk) + BITS_TO_LONGS(nbits) * sizeof(long); chunk = vzalloc_node(nbytes, nid); @@ -242,7 +243,7 @@ void gen_pool_destroy(struct gen_pool *pool) struct list_head *_chunk, *_next_chunk; struct gen_pool_chunk *chunk; int order = pool->min_alloc_order; - int bit, end_bit; + unsigned long bit, end_bit; list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); @@ -278,7 +279,7 @@ unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size, struct gen_pool_chunk *chunk; unsigned long addr = 0; int order = pool->min_alloc_order; - int nbits, start_bit, end_bit, remain; + unsigned long nbits, start_bit, end_bit, remain; #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG BUG_ON(in_nmi()); @@ -487,7 +488,7 @@ void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, size_t size, { struct gen_pool_chunk *chunk; int order = pool->min_alloc_order; - int start_bit, nbits, remain; + unsigned long start_bit, nbits, remain; #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG BUG_ON(in_nmi()); @@ -755,7 +756,7 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, index = bitmap_find_next_zero_area(map, size, start, nr, 0); while (index < size) { - int next_bit = find_next_bit(map, size, index + nr); + unsigned long next_bit = find_next_bit(map, size, index + nr); if ((next_bit - index) < len) { len = next_bit - index; start_bit = index; diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 1635111c5bd2..a21e6a5792c5 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1658,7 +1658,7 @@ static int copy_compat_iovec_from_user(struct iovec *iov, (const struct compat_iovec __user *)uvec; int ret = -EFAULT, i; - if (!user_access_begin(uvec, nr_segs * sizeof(*uvec))) + if (!user_access_begin(uiov, nr_segs * sizeof(*uiov))) return -EFAULT; for (i = 0; i < nr_segs; i++) { diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index b4c0df6d706d..c770570bfe4f 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -48,7 +48,7 @@ endif endif quiet_cmd_unroll = UNROLL $@ - cmd_unroll = $(AWK) -f$(srctree)/$(src)/unroll.awk -vN=$* < $< > $@ + cmd_unroll = $(AWK) -v N=$* -f $(srctree)/$(src)/unroll.awk < $< > $@ targets += int1.c int2.c int4.c int8.c int16.c int32.c $(obj)/int%.c: $(src)/int.uc $(src)/unroll.awk FORCE diff --git a/lib/test_kasan.c b/lib/test_kasan.c index 662f862702fc..2947274cc2d3 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -25,7 +25,7 @@ #include "../mm/kasan/kasan.h" -#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_SHADOW_SCALE_SIZE) +#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) /* * We assign some test results to these globals to make sure the tests diff --git a/lib/test_kasan_module.c b/lib/test_kasan_module.c index 62a87854b120..3b4cc77992d2 100644 --- a/lib/test_kasan_module.c +++ b/lib/test_kasan_module.c @@ -15,7 +15,7 @@ #include "../mm/kasan/kasan.h" -#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_SHADOW_SCALE_SIZE) +#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) static noinline void __init copy_user_test(void) { diff --git a/lib/zlib_dfltcc/Makefile b/lib/zlib_dfltcc/Makefile index 8e4d5afbbb10..66e1c96387c4 100644 --- a/lib/zlib_dfltcc/Makefile +++ b/lib/zlib_dfltcc/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o -zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o dfltcc_syms.o +zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o diff --git a/lib/zlib_dfltcc/dfltcc.c b/lib/zlib_dfltcc/dfltcc.c index c30de430b30c..782f76e9d4da 100644 --- a/lib/zlib_dfltcc/dfltcc.c +++ b/lib/zlib_dfltcc/dfltcc.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: Zlib /* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ -#include <linux/zutil.h> +#include <linux/export.h> +#include <linux/module.h> #include "dfltcc_util.h" #include "dfltcc.h" @@ -53,3 +54,6 @@ void dfltcc_reset( dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE; dfltcc_state->param.ribm = DFLTCC_RIBM; } +EXPORT_SYMBOL(dfltcc_reset); + +MODULE_LICENSE("GPL"); diff --git a/lib/zlib_dfltcc/dfltcc_deflate.c b/lib/zlib_dfltcc/dfltcc_deflate.c index 00c185101c6d..6c946e8532ee 100644 --- a/lib/zlib_dfltcc/dfltcc_deflate.c +++ b/lib/zlib_dfltcc/dfltcc_deflate.c @@ -4,6 +4,7 @@ #include "dfltcc_util.h" #include "dfltcc.h" #include <asm/setup.h> +#include <linux/export.h> #include <linux/zutil.h> /* @@ -34,6 +35,7 @@ int dfltcc_can_deflate( return 1; } +EXPORT_SYMBOL(dfltcc_can_deflate); static void dfltcc_gdht( z_streamp strm @@ -277,3 +279,4 @@ again: goto again; /* deflate() must use all input or all output */ return 1; } +EXPORT_SYMBOL(dfltcc_deflate); diff --git a/lib/zlib_dfltcc/dfltcc_inflate.c b/lib/zlib_dfltcc/dfltcc_inflate.c index db107016d29b..fb60b5a6a1cb 100644 --- a/lib/zlib_dfltcc/dfltcc_inflate.c +++ b/lib/zlib_dfltcc/dfltcc_inflate.c @@ -125,7 +125,7 @@ dfltcc_inflate_action dfltcc_inflate( param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1); if (param->hl) param->nt = 0; /* Honor history for the first block */ - param->cv = state->flags ? REVERSE(state->check) : state->check; + param->cv = state->check; /* Inflate */ do { @@ -138,7 +138,7 @@ dfltcc_inflate_action dfltcc_inflate( state->bits = param->sbb; state->whave = param->hl; state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1); - state->check = state->flags ? REVERSE(param->cv) : param->cv; + state->check = param->cv; if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { /* Report an error if stream is corrupted */ state->mode = BAD; diff --git a/lib/zlib_dfltcc/dfltcc_syms.c b/lib/zlib_dfltcc/dfltcc_syms.c deleted file mode 100644 index 6f23481804c1..000000000000 --- a/lib/zlib_dfltcc/dfltcc_syms.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/lib/zlib_dfltcc/dfltcc_syms.c - * - * Exported symbols for the s390 zlib dfltcc support. - * - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/zlib.h> -#include "dfltcc.h" - -EXPORT_SYMBOL(dfltcc_can_deflate); -EXPORT_SYMBOL(dfltcc_deflate); -EXPORT_SYMBOL(dfltcc_reset); -MODULE_LICENSE("GPL"); |