Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: "Incoming: - a small number of updates to scripts/, ocfs2 and fs/buffer.c - most of MM I still have quite a lot of material (mostly not MM) staged after linux-next due to -next dependencies. I'll send those across next week as the preprequisites get merged up" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (135 commits) mm/page_io.c: annotate refault stalls from swap_readpage mm/Kconfig: fix trivial help text punctuation mm/Kconfig: fix indentation mm/memory_hotplug.c: remove __online_page_set_limits() mm: fix typos in comments when calling __SetPageUptodate() mm: fix struct member name in function comments mm/shmem.c: cast the type of unmap_start to u64 mm: shmem: use proper gfp flags for shmem_writepage() mm/shmem.c: make array 'values' static const, makes object smaller userfaultfd: require CAP_SYS_PTRACE for UFFD_FEATURE_EVENT_FORK fs/userfaultfd.c: wp: clear VM_UFFD_MISSING or VM_UFFD_WP during userfaultfd_register() userfaultfd: wrap the common dst_vma check into an inlined function userfaultfd: remove unnecessary WARN_ON() in __mcopy_atomic_hugetlb() userfaultfd: use vma_pagesize for all huge page size calculation mm/madvise.c: use PAGE_ALIGN[ED] for range checking mm/madvise.c: replace with page_size() in madvise_inject_error() mm/mmap.c: make vma_merge() comment more easy to understand mm/hwpoison-inject: use DEFINE_DEBUGFS_ATTRIBUTE to define debugfs fops autonuma: reduce cache footprint when scanning page tables autonuma: fix watermark checking in migrate_balanced_pgdat() ...
This commit is contained in:
@@ -6,6 +6,9 @@ config HAVE_ARCH_KASAN
|
||||
config HAVE_ARCH_KASAN_SW_TAGS
|
||||
bool
|
||||
|
||||
config HAVE_ARCH_KASAN_VMALLOC
|
||||
bool
|
||||
|
||||
config CC_HAS_KASAN_GENERIC
|
||||
def_bool $(cc-option, -fsanitize=kernel-address)
|
||||
|
||||
@@ -142,6 +145,19 @@ config KASAN_SW_TAGS_IDENTIFY
|
||||
(use-after-free or out-of-bounds) at the cost of increased
|
||||
memory consumption.
|
||||
|
||||
config KASAN_VMALLOC
|
||||
bool "Back mappings in vmalloc space with real shadow memory"
|
||||
depends on KASAN && 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
|
||||
vmalloc space.
|
||||
|
||||
Enabling this option will hook in to vmap/vmalloc and back those
|
||||
mappings with real shadow memory allocated on demand. This allows
|
||||
for KASAN to detect more sorts of errors (and to support vmapped
|
||||
stacks), but at the cost of higher memory usage.
|
||||
|
||||
config TEST_KASAN
|
||||
tristate "Module for testing KASAN for bug detection"
|
||||
depends on m && KASAN
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
@@ -748,6 +749,30 @@ static noinline void __init kmalloc_double_kzfree(void)
|
||||
kzfree(ptr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KASAN_VMALLOC
|
||||
static noinline void __init vmalloc_oob(void)
|
||||
{
|
||||
void *area;
|
||||
|
||||
pr_info("vmalloc out-of-bounds\n");
|
||||
|
||||
/*
|
||||
* We have to be careful not to hit the guard page.
|
||||
* The MMU will catch that and crash us.
|
||||
*/
|
||||
area = vmalloc(3000);
|
||||
if (!area) {
|
||||
pr_err("Allocation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
((volatile char *)area)[3100];
|
||||
vfree(area);
|
||||
}
|
||||
#else
|
||||
static void __init vmalloc_oob(void) {}
|
||||
#endif
|
||||
|
||||
static int __init kmalloc_tests_init(void)
|
||||
{
|
||||
/*
|
||||
@@ -793,6 +818,7 @@ static int __init kmalloc_tests_init(void)
|
||||
kasan_strings();
|
||||
kasan_bitops();
|
||||
kmalloc_double_kzfree();
|
||||
vmalloc_oob();
|
||||
|
||||
kasan_restore_multi_shot(multishot);
|
||||
|
||||
|
||||
+32
-14
@@ -761,23 +761,12 @@ static int __init initialize_ptr_random(void)
|
||||
early_initcall(initialize_ptr_random);
|
||||
|
||||
/* Maps a pointer to a 32 bit unique identifier. */
|
||||
static char *ptr_to_id(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
|
||||
{
|
||||
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
|
||||
unsigned long hashval;
|
||||
|
||||
/* When debugging early boot use non-cryptographically secure hash. */
|
||||
if (unlikely(debug_boot_weak_hash)) {
|
||||
hashval = hash_long((unsigned long)ptr, 32);
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
/* string length must be less than default_width */
|
||||
return error_string(buf, end, str, spec);
|
||||
}
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key))
|
||||
return -EAGAIN;
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
|
||||
@@ -789,6 +778,35 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr,
|
||||
#else
|
||||
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
||||
#endif
|
||||
*hashval_out = hashval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
|
||||
{
|
||||
return __ptr_to_hashval(ptr, hashval_out);
|
||||
}
|
||||
|
||||
static char *ptr_to_id(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
{
|
||||
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
|
||||
unsigned long hashval;
|
||||
int ret;
|
||||
|
||||
/* When debugging early boot use non-cryptographically secure hash. */
|
||||
if (unlikely(debug_boot_weak_hash)) {
|
||||
hashval = hash_long((unsigned long)ptr, 32);
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
ret = __ptr_to_hashval(ptr, &hashval);
|
||||
if (ret) {
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
/* string length must be less than default_width */
|
||||
return error_string(buf, end, str, spec);
|
||||
}
|
||||
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user