Skip to content

Commit 43c4f67

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "7 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: mm: fix false-positive WARN_ON() in truncate/invalidate for hugetlb kasan: support use-after-scope detection kasan: update kasan_global for gcc 7 lib/debugobjects: export for use in modules zram: fix unbalanced idr management at hot removal thp: fix corner case of munlock() of PTE-mapped THPs mm, thp: propagation of conditional compilation in khugepaged.c
2 parents f513581 + 5cbc198 commit 43c4f67

11 files changed

Lines changed: 94 additions & 14 deletions

File tree

drivers/block/zram/zram_drv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,8 @@ static ssize_t hot_remove_store(struct class *class,
14031403
zram = idr_find(&zram_index_idr, dev_id);
14041404
if (zram) {
14051405
ret = zram_remove(zram);
1406-
idr_remove(&zram_index_idr, dev_id);
1406+
if (!ret)
1407+
idr_remove(&zram_index_idr, dev_id);
14071408
} else {
14081409
ret = -ENODEV;
14091410
}

include/linux/compiler-gcc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@
263263
#endif
264264
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
265265

266-
#if GCC_VERSION >= 50000
266+
#if GCC_VERSION >= 70000
267+
#define KASAN_ABI_VERSION 5
268+
#elif GCC_VERSION >= 50000
267269
#define KASAN_ABI_VERSION 4
268270
#elif GCC_VERSION >= 40902
269271
#define KASAN_ABI_VERSION 3

include/linux/pagemap.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,16 +374,13 @@ static inline struct page *read_mapping_page(struct address_space *mapping,
374374
}
375375

376376
/*
377-
* Get the offset in PAGE_SIZE.
378-
* (TODO: hugepage should have ->index in PAGE_SIZE)
377+
* Get index of the page with in radix-tree
378+
* (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE)
379379
*/
380-
static inline pgoff_t page_to_pgoff(struct page *page)
380+
static inline pgoff_t page_to_index(struct page *page)
381381
{
382382
pgoff_t pgoff;
383383

384-
if (unlikely(PageHeadHuge(page)))
385-
return page->index << compound_order(page);
386-
387384
if (likely(!PageTransTail(page)))
388385
return page->index;
389386

@@ -396,6 +393,18 @@ static inline pgoff_t page_to_pgoff(struct page *page)
396393
return pgoff;
397394
}
398395

396+
/*
397+
* Get the offset in PAGE_SIZE.
398+
* (TODO: hugepage should have ->index in PAGE_SIZE)
399+
*/
400+
static 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+
399408
/*
400409
* Return byte-offset into filesystem object for page.
401410
*/

lib/debugobjects.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ void debug_object_init(void *addr, struct debug_obj_descr *descr)
362362

363363
__debug_object_init(addr, descr, 0);
364364
}
365+
EXPORT_SYMBOL_GPL(debug_object_init);
365366

366367
/**
367368
* 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)
376377

377378
__debug_object_init(addr, descr, 1);
378379
}
380+
EXPORT_SYMBOL_GPL(debug_object_init_on_stack);
379381

380382
/**
381383
* 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)
449451
}
450452
return 0;
451453
}
454+
EXPORT_SYMBOL_GPL(debug_object_activate);
452455

453456
/**
454457
* 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)
496499

497500
raw_spin_unlock_irqrestore(&db->lock, flags);
498501
}
502+
EXPORT_SYMBOL_GPL(debug_object_deactivate);
499503

500504
/**
501505
* 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)
542546
out_unlock:
543547
raw_spin_unlock_irqrestore(&db->lock, flags);
544548
}
549+
EXPORT_SYMBOL_GPL(debug_object_destroy);
545550

546551
/**
547552
* 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)
582587
out_unlock:
583588
raw_spin_unlock_irqrestore(&db->lock, flags);
584589
}
590+
EXPORT_SYMBOL_GPL(debug_object_free);
585591

586592
/**
587593
* 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)
626632

627633
raw_spin_unlock_irqrestore(&db->lock, flags);
628634
}
635+
EXPORT_SYMBOL_GPL(debug_object_assert_init);
629636

630637
/**
631638
* 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,
673680

674681
raw_spin_unlock_irqrestore(&db->lock, flags);
675682
}
683+
EXPORT_SYMBOL_GPL(debug_object_active_state);
676684

677685
#ifdef CONFIG_DEBUG_OBJECTS_FREE
678686
static void __debug_check_no_obj_freed(const void *address, unsigned long size)

lib/test_kasan.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
#include <linux/uaccess.h>
2121
#include <linux/module.h>
2222

23+
/*
24+
* Note: test functions are marked noinline so that their names appear in
25+
* reports.
26+
*/
27+
2328
static noinline void __init kmalloc_oob_right(void)
2429
{
2530
char *ptr;
@@ -411,6 +416,29 @@ static noinline void __init copy_user_test(void)
411416
kfree(kmem);
412417
}
413418

419+
static 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+
414442
static int __init kmalloc_tests_init(void)
415443
{
416444
kmalloc_oob_right();
@@ -436,6 +464,7 @@ static int __init kmalloc_tests_init(void)
436464
kasan_global_oob();
437465
ksize_unpoisons_memory();
438466
copy_user_test();
467+
use_after_scope_test();
439468
return -EAGAIN;
440469
}
441470

mm/kasan/kasan.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,25 @@ EXPORT_SYMBOL(__asan_storeN_noabort);
764764
void __asan_handle_no_return(void) {}
765765
EXPORT_SYMBOL(__asan_handle_no_return);
766766

767+
/* Emitted by compiler to poison large objects when they go out of scope. */
768+
void __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+
}
777+
EXPORT_SYMBOL(__asan_poison_stack_memory);
778+
779+
/* Emitted by compiler to unpoison large objects when they go into scope. */
780+
void __asan_unpoison_stack_memory(const void *addr, size_t size)
781+
{
782+
kasan_unpoison_shadow(addr, size);
783+
}
784+
EXPORT_SYMBOL(__asan_unpoison_stack_memory);
785+
767786
#ifdef CONFIG_MEMORY_HOTPLUG
768787
static int kasan_mem_notifier(struct notifier_block *nb,
769788
unsigned long action, void *data)

mm/kasan/kasan.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define KASAN_STACK_MID 0xF2
2222
#define KASAN_STACK_RIGHT 0xF3
2323
#define KASAN_STACK_PARTIAL 0xF4
24+
#define KASAN_USE_AFTER_SCOPE 0xF8
2425

2526
/* Don't break randconfig/all*config builds */
2627
#ifndef KASAN_ABI_VERSION
@@ -53,6 +54,9 @@ struct kasan_global {
5354
#if KASAN_ABI_VERSION >= 4
5455
struct kasan_source_location *location;
5556
#endif
57+
#if KASAN_ABI_VERSION >= 5
58+
char *odr_indicator;
59+
#endif
5660
};
5761

5862
/**

mm/kasan/report.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ static void print_error_description(struct kasan_access_info *info)
9090
case KASAN_KMALLOC_FREE:
9191
bug_type = "use-after-free";
9292
break;
93+
case KASAN_USE_AFTER_SCOPE:
94+
bug_type = "use-after-scope";
95+
break;
9396
}
9497

9598
pr_err("BUG: KASAN: %s in %pS at addr %p\n",

mm/khugepaged.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static struct khugepaged_scan khugepaged_scan = {
103103
.mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
104104
};
105105

106+
#ifdef CONFIG_SYSFS
106107
static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
107108
struct kobj_attribute *attr,
108109
char *buf)
@@ -295,6 +296,7 @@ struct attribute_group khugepaged_attr_group = {
295296
.attrs = khugepaged_attr,
296297
.name = "khugepaged",
297298
};
299+
#endif /* CONFIG_SYSFS */
298300

299301
#define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB)
300302

mm/mlock.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,13 @@ unsigned int munlock_vma_page(struct page *page)
190190
*/
191191
spin_lock_irq(zone_lru_lock(zone));
192192

193-
nr_pages = hpage_nr_pages(page);
194-
if (!TestClearPageMlocked(page))
193+
if (!TestClearPageMlocked(page)) {
194+
/* Potentially, PTE-mapped THP: do not skip the rest PTEs */
195+
nr_pages = 1;
195196
goto unlock_out;
197+
}
196198

199+
nr_pages = hpage_nr_pages(page);
197200
__mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
198201

199202
if (__munlock_isolate_lru_page(page, true)) {

0 commit comments

Comments
 (0)