aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/zram/zram_drv.c3
-rw-r--r--include/linux/compiler-gcc.h4
-rw-r--r--include/linux/pagemap.h21
-rw-r--r--lib/debugobjects.c8
-rw-r--r--lib/test_kasan.c29
-rw-r--r--mm/kasan/kasan.c19
-rw-r--r--mm/kasan/kasan.h4
-rw-r--r--mm/kasan/report.c3
-rw-r--r--mm/khugepaged.c2
-rw-r--r--mm/mlock.c7
-rw-r--r--mm/truncate.c8
11 files changed, 94 insertions, 14 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 04365b17ee67..5163c8f918cb 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1403,7 +1403,8 @@ static ssize_t hot_remove_store(struct class *class,
1403 zram = idr_find(&zram_index_idr, dev_id); 1403 zram = idr_find(&zram_index_idr, dev_id);
1404 if (zram) { 1404 if (zram) {
1405 ret = zram_remove(zram); 1405 ret = zram_remove(zram);
1406 idr_remove(&zram_index_idr, dev_id); 1406 if (!ret)
1407 idr_remove(&zram_index_idr, dev_id);
1407 } else { 1408 } else {
1408 ret = -ENODEV; 1409 ret = -ENODEV;
1409 } 1410 }
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 432f5c97e18f..928e5ca0caee 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -263,7 +263,9 @@
263#endif 263#endif
264#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */ 264#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
265 265
266#if GCC_VERSION >= 50000 266#if GCC_VERSION >= 70000
267#define KASAN_ABI_VERSION 5
268#elif GCC_VERSION >= 50000
267#define KASAN_ABI_VERSION 4 269#define KASAN_ABI_VERSION 4
268#elif GCC_VERSION >= 40902 270#elif GCC_VERSION >= 40902
269#define KASAN_ABI_VERSION 3 271#define KASAN_ABI_VERSION 3
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index dd15d39e1985..7dbe9148b2f8 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -374,16 +374,13 @@ static inline struct page *read_mapping_page(struct address_space *mapping,
374} 374}
375 375
376/* 376/*
377 * Get the offset in PAGE_SIZE. 377 * Get index of the page with in radix-tree
378 * (TODO: hugepage should have ->index in PAGE_SIZE) 378 * (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE)
379 */ 379 */
380static inline pgoff_t page_to_pgoff(struct page *page) 380static inline pgoff_t page_to_index(struct page *page)
381{ 381{
382 pgoff_t pgoff; 382 pgoff_t pgoff;
383 383
384 if (unlikely(PageHeadHuge(page)))
385 return page->index << compound_order(page);
386
387 if (likely(!PageTransTail(page))) 384 if (likely(!PageTransTail(page)))
388 return page->index; 385 return page->index;
389 386
@@ -397,6 +394,18 @@ static inline pgoff_t page_to_pgoff(struct page *page)
397} 394}
398 395
399/* 396/*
397 * Get the offset in PAGE_SIZE.
398 * (TODO: hugepage should have ->index in PAGE_SIZE)
399 */
400static inline pgoff_t page_to_pgoff(struct page *page)
401{
402 if (unlikely(PageHeadHuge(page)))
403 return page->index << compound_order(page);
404
405 return page_to_index(page);
406}
407
408/*
400 * Return byte-offset into filesystem object for page. 409 * Return byte-offset into filesystem object for page.
401 */ 410 */
402static inline loff_t page_offset(struct page *page) 411static inline loff_t page_offset(struct page *page)
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index a8e12601eb37..056052dc8e91 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -362,6 +362,7 @@ void debug_object_init(void *addr, struct debug_obj_descr *descr)
362 362
363 __debug_object_init(addr, descr, 0); 363 __debug_object_init(addr, descr, 0);
364} 364}
365EXPORT_SYMBOL_GPL(debug_object_init);
365 366
366/** 367/**
367 * debug_object_init_on_stack - debug checks when an object on stack is 368 * debug_object_init_on_stack - debug checks when an object on stack is
@@ -376,6 +377,7 @@ void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr)
376 377
377 __debug_object_init(addr, descr, 1); 378 __debug_object_init(addr, descr, 1);
378} 379}
380EXPORT_SYMBOL_GPL(debug_object_init_on_stack);
379 381
380/** 382/**
381 * debug_object_activate - debug checks when an object is activated 383 * debug_object_activate - debug checks when an object is activated
@@ -449,6 +451,7 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
449 } 451 }
450 return 0; 452 return 0;
451} 453}
454EXPORT_SYMBOL_GPL(debug_object_activate);
452 455
453/** 456/**
454 * debug_object_deactivate - debug checks when an object is deactivated 457 * debug_object_deactivate - debug checks when an object is deactivated
@@ -496,6 +499,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
496 499
497 raw_spin_unlock_irqrestore(&db->lock, flags); 500 raw_spin_unlock_irqrestore(&db->lock, flags);
498} 501}
502EXPORT_SYMBOL_GPL(debug_object_deactivate);
499 503
500/** 504/**
501 * debug_object_destroy - debug checks when an object is destroyed 505 * debug_object_destroy - debug checks when an object is destroyed
@@ -542,6 +546,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
542out_unlock: 546out_unlock:
543 raw_spin_unlock_irqrestore(&db->lock, flags); 547 raw_spin_unlock_irqrestore(&db->lock, flags);
544} 548}
549EXPORT_SYMBOL_GPL(debug_object_destroy);
545 550
546/** 551/**
547 * debug_object_free - debug checks when an object is freed 552 * debug_object_free - debug checks when an object is freed
@@ -582,6 +587,7 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
582out_unlock: 587out_unlock:
583 raw_spin_unlock_irqrestore(&db->lock, flags); 588 raw_spin_unlock_irqrestore(&db->lock, flags);
584} 589}
590EXPORT_SYMBOL_GPL(debug_object_free);
585 591
586/** 592/**
587 * debug_object_assert_init - debug checks when object should be init-ed 593 * debug_object_assert_init - debug checks when object should be init-ed
@@ -626,6 +632,7 @@ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
626 632
627 raw_spin_unlock_irqrestore(&db->lock, flags); 633 raw_spin_unlock_irqrestore(&db->lock, flags);
628} 634}
635EXPORT_SYMBOL_GPL(debug_object_assert_init);
629 636
630/** 637/**
631 * debug_object_active_state - debug checks object usage state machine 638 * debug_object_active_state - debug checks object usage state machine
@@ -673,6 +680,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr,
673 680
674 raw_spin_unlock_irqrestore(&db->lock, flags); 681 raw_spin_unlock_irqrestore(&db->lock, flags);
675} 682}
683EXPORT_SYMBOL_GPL(debug_object_active_state);
676 684
677#ifdef CONFIG_DEBUG_OBJECTS_FREE 685#ifdef CONFIG_DEBUG_OBJECTS_FREE
678static void __debug_check_no_obj_freed(const void *address, unsigned long size) 686static void __debug_check_no_obj_freed(const void *address, unsigned long size)
diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 5e51872b3fc1..fbdf87920093 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -20,6 +20,11 @@
20#include <linux/uaccess.h> 20#include <linux/uaccess.h>
21#include <linux/module.h> 21#include <linux/module.h>
22 22
23/*
24 * Note: test functions are marked noinline so that their names appear in
25 * reports.
26 */
27
23static noinline void __init kmalloc_oob_right(void) 28static noinline void __init kmalloc_oob_right(void)
24{ 29{
25 char *ptr; 30 char *ptr;
@@ -411,6 +416,29 @@ static noinline void __init copy_user_test(void)
411 kfree(kmem); 416 kfree(kmem);
412} 417}
413 418
419static noinline void __init use_after_scope_test(void)
420{
421 volatile char *volatile p;
422
423 pr_info("use-after-scope on int\n");
424 {
425 int local = 0;
426
427 p = (char *)&local;
428 }
429 p[0] = 1;
430 p[3] = 1;
431
432 pr_info("use-after-scope on array\n");
433 {
434 char local[1024] = {0};
435
436 p = local;
437 }
438 p[0] = 1;
439 p[1023] = 1;
440}
441
414static int __init kmalloc_tests_init(void) 442static int __init kmalloc_tests_init(void)
415{ 443{
416 kmalloc_oob_right(); 444 kmalloc_oob_right();
@@ -436,6 +464,7 @@ static int __init kmalloc_tests_init(void)
436 kasan_global_oob(); 464 kasan_global_oob();
437 ksize_unpoisons_memory(); 465 ksize_unpoisons_memory();
438 copy_user_test(); 466 copy_user_test();
467 use_after_scope_test();
439 return -EAGAIN; 468 return -EAGAIN;
440} 469}
441 470
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 70c009741aab..0e9505f66ec1 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -764,6 +764,25 @@ EXPORT_SYMBOL(__asan_storeN_noabort);
764void __asan_handle_no_return(void) {} 764void __asan_handle_no_return(void) {}
765EXPORT_SYMBOL(__asan_handle_no_return); 765EXPORT_SYMBOL(__asan_handle_no_return);
766 766
767/* Emitted by compiler to poison large objects when they go out of scope. */
768void __asan_poison_stack_memory(const void *addr, size_t size)
769{
770 /*
771 * Addr is KASAN_SHADOW_SCALE_SIZE-aligned and the object is surrounded
772 * by redzones, so we simply round up size to simplify logic.
773 */
774 kasan_poison_shadow(addr, round_up(size, KASAN_SHADOW_SCALE_SIZE),
775 KASAN_USE_AFTER_SCOPE);
776}
777EXPORT_SYMBOL(__asan_poison_stack_memory);
778
779/* Emitted by compiler to unpoison large objects when they go into scope. */
780void __asan_unpoison_stack_memory(const void *addr, size_t size)
781{
782 kasan_unpoison_shadow(addr, size);
783}
784EXPORT_SYMBOL(__asan_unpoison_stack_memory);
785
767#ifdef CONFIG_MEMORY_HOTPLUG 786#ifdef CONFIG_MEMORY_HOTPLUG
768static int kasan_mem_notifier(struct notifier_block *nb, 787static int kasan_mem_notifier(struct notifier_block *nb,
769 unsigned long action, void *data) 788 unsigned long action, void *data)
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index e5c2181fee6f..1c260e6b3b3c 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -21,6 +21,7 @@
21#define KASAN_STACK_MID 0xF2 21#define KASAN_STACK_MID 0xF2
22#define KASAN_STACK_RIGHT 0xF3 22#define KASAN_STACK_RIGHT 0xF3
23#define KASAN_STACK_PARTIAL 0xF4 23#define KASAN_STACK_PARTIAL 0xF4
24#define KASAN_USE_AFTER_SCOPE 0xF8
24 25
25/* Don't break randconfig/all*config builds */ 26/* Don't break randconfig/all*config builds */
26#ifndef KASAN_ABI_VERSION 27#ifndef KASAN_ABI_VERSION
@@ -53,6 +54,9 @@ struct kasan_global {
53#if KASAN_ABI_VERSION >= 4 54#if KASAN_ABI_VERSION >= 4
54 struct kasan_source_location *location; 55 struct kasan_source_location *location;
55#endif 56#endif
57#if KASAN_ABI_VERSION >= 5
58 char *odr_indicator;
59#endif
56}; 60};
57 61
58/** 62/**
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 24c1211fe9d5..073325aedc68 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -90,6 +90,9 @@ static void print_error_description(struct kasan_access_info *info)
90 case KASAN_KMALLOC_FREE: 90 case KASAN_KMALLOC_FREE:
91 bug_type = "use-after-free"; 91 bug_type = "use-after-free";
92 break; 92 break;
93 case KASAN_USE_AFTER_SCOPE:
94 bug_type = "use-after-scope";
95 break;
93 } 96 }
94 97
95 pr_err("BUG: KASAN: %s in %pS at addr %p\n", 98 pr_err("BUG: KASAN: %s in %pS at addr %p\n",
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 728d7790dc2d..87e1a7ca3846 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -103,6 +103,7 @@ static struct khugepaged_scan khugepaged_scan = {
103 .mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head), 103 .mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
104}; 104};
105 105
106#ifdef CONFIG_SYSFS
106static ssize_t scan_sleep_millisecs_show(struct kobject *kobj, 107static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
107 struct kobj_attribute *attr, 108 struct kobj_attribute *attr,
108 char *buf) 109 char *buf)
@@ -295,6 +296,7 @@ struct attribute_group khugepaged_attr_group = {
295 .attrs = khugepaged_attr, 296 .attrs = khugepaged_attr,
296 .name = "khugepaged", 297 .name = "khugepaged",
297}; 298};
299#endif /* CONFIG_SYSFS */
298 300
299#define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB) 301#define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB)
300 302
diff --git a/mm/mlock.c b/mm/mlock.c
index 145a4258ddbc..cdbed8aaa426 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -190,10 +190,13 @@ unsigned int munlock_vma_page(struct page *page)
190 */ 190 */
191 spin_lock_irq(zone_lru_lock(zone)); 191 spin_lock_irq(zone_lru_lock(zone));
192 192
193 nr_pages = hpage_nr_pages(page); 193 if (!TestClearPageMlocked(page)) {
194 if (!TestClearPageMlocked(page)) 194 /* Potentially, PTE-mapped THP: do not skip the rest PTEs */
195 nr_pages = 1;
195 goto unlock_out; 196 goto unlock_out;
197 }
196 198
199 nr_pages = hpage_nr_pages(page);
197 __mod_zone_page_state(zone, NR_MLOCK, -nr_pages); 200 __mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
198 201
199 if (__munlock_isolate_lru_page(page, true)) { 202 if (__munlock_isolate_lru_page(page, true)) {
diff --git a/mm/truncate.c b/mm/truncate.c
index a01cce450a26..8d8c62d89e6d 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -283,7 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
283 283
284 if (!trylock_page(page)) 284 if (!trylock_page(page))
285 continue; 285 continue;
286 WARN_ON(page_to_pgoff(page) != index); 286 WARN_ON(page_to_index(page) != index);
287 if (PageWriteback(page)) { 287 if (PageWriteback(page)) {
288 unlock_page(page); 288 unlock_page(page);
289 continue; 289 continue;
@@ -371,7 +371,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
371 } 371 }
372 372
373 lock_page(page); 373 lock_page(page);
374 WARN_ON(page_to_pgoff(page) != index); 374 WARN_ON(page_to_index(page) != index);
375 wait_on_page_writeback(page); 375 wait_on_page_writeback(page);
376 truncate_inode_page(mapping, page); 376 truncate_inode_page(mapping, page);
377 unlock_page(page); 377 unlock_page(page);
@@ -492,7 +492,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
492 if (!trylock_page(page)) 492 if (!trylock_page(page))
493 continue; 493 continue;
494 494
495 WARN_ON(page_to_pgoff(page) != index); 495 WARN_ON(page_to_index(page) != index);
496 496
497 /* Middle of THP: skip */ 497 /* Middle of THP: skip */
498 if (PageTransTail(page)) { 498 if (PageTransTail(page)) {
@@ -612,7 +612,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
612 } 612 }
613 613
614 lock_page(page); 614 lock_page(page);
615 WARN_ON(page_to_pgoff(page) != index); 615 WARN_ON(page_to_index(page) != index);
616 if (page->mapping != mapping) { 616 if (page->mapping != mapping) {
617 unlock_page(page); 617 unlock_page(page);
618 continue; 618 continue;