Skip to content

Commit 1b97073

Browse files
dvyukovpundiramit
authored andcommitted
UPSTREAM: kasan: support use-after-scope detection
Gcc revision 241896 implements use-after-scope detection. Will be available in gcc 7. Support it in KASAN. Gcc emits 2 new callbacks to poison/unpoison large stack objects when they go in/out of scope. Implement the callbacks and add a test. [dvyukov@google.com: v3] Link: http://lkml.kernel.org/r/1479998292-144502-1-git-send-email-dvyukov@google.com Link: http://lkml.kernel.org/r/1479226045-145148-1-git-send-email-dvyukov@google.com Signed-off-by: Dmitry Vyukov <dvyukov@google.com> Acked-by: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Alexander Potapenko <glider@google.com> Cc: <stable@vger.kernel.org> [4.0+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Bug: 64145065 (cherry-picked from 828347f8f9a558cf1af2faa46387a26564f2ac3e) Change-Id: Ib9cb585efbe98ba11a7efbd233ebd97cb4214a92 Signed-off-by: Paul Lawrence <paullawrence@google.com>
1 parent 1689b56 commit 1b97073

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

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: 1 addition & 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

mm/kasan/report.c

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

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

0 commit comments

Comments
 (0)