Message ID | 17b812a3c28024acfca9b1a9e45c8235b35efa32.1628709663.git.andreyknvl@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | kasan: test: avoid crashing the kernel with HW_TAGS | expand |
On Wed, 11 Aug 2021 at 21:30, <andrey.konovalov@linux.dev> wrote: > From: Andrey Konovalov <andreyknvl@gmail.com> > > copy_user_test() does writes past the allocated object. As the result, > it corrupts kernel memory, which might lead to crashes with the HW_TAGS > mode, as it neither uses quarantine nor redzones. > > (Technically, this test can't yet be enabled with the HW_TAGS mode, but > this will be implemented in the future.) > > Adjust the test to only write memory within the aligned kmalloc object. > > Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com> Reviewed-by: Marco Elver <elver@google.com> > --- > lib/test_kasan_module.c | 18 ++++++++---------- > 1 file changed, 8 insertions(+), 10 deletions(-) > > diff --git a/lib/test_kasan_module.c b/lib/test_kasan_module.c > index f1017f345d6c..fa73b9df0be4 100644 > --- a/lib/test_kasan_module.c > +++ b/lib/test_kasan_module.c > @@ -15,13 +15,11 @@ > > #include "../mm/kasan/kasan.h" > > -#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) > - > static noinline void __init copy_user_test(void) > { > char *kmem; > char __user *usermem; > - size_t size = 10; > + size_t size = 128 - KASAN_GRANULE_SIZE; > int __maybe_unused unused; > > kmem = kmalloc(size, GFP_KERNEL); > @@ -38,25 +36,25 @@ static noinline void __init copy_user_test(void) > } > > pr_info("out-of-bounds in copy_from_user()\n"); > - unused = copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); > + unused = copy_from_user(kmem, usermem, size + 1); > > pr_info("out-of-bounds in copy_to_user()\n"); > - unused = copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF); > + unused = copy_to_user(usermem, kmem, size + 1); > > pr_info("out-of-bounds in __copy_from_user()\n"); > - unused = __copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); > + unused = __copy_from_user(kmem, usermem, size + 1); > > pr_info("out-of-bounds in __copy_to_user()\n"); > - unused = __copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF); > + unused = __copy_to_user(usermem, kmem, size + 1); > > pr_info("out-of-bounds in __copy_from_user_inatomic()\n"); > - unused = __copy_from_user_inatomic(kmem, usermem, size + 1 + OOB_TAG_OFF); > + unused = __copy_from_user_inatomic(kmem, usermem, size + 1); > > pr_info("out-of-bounds in __copy_to_user_inatomic()\n"); > - unused = __copy_to_user_inatomic(usermem, kmem, size + 1 + OOB_TAG_OFF); > + unused = __copy_to_user_inatomic(usermem, kmem, size + 1); > > pr_info("out-of-bounds in strncpy_from_user()\n"); > - unused = strncpy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); > + unused = strncpy_from_user(kmem, usermem, size + 1); > > vm_munmap((unsigned long)usermem, PAGE_SIZE); > kfree(kmem); > -- > 2.25.1 >
diff --git a/lib/test_kasan_module.c b/lib/test_kasan_module.c index f1017f345d6c..fa73b9df0be4 100644 --- a/lib/test_kasan_module.c +++ b/lib/test_kasan_module.c @@ -15,13 +15,11 @@ #include "../mm/kasan/kasan.h" -#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) - static noinline void __init copy_user_test(void) { char *kmem; char __user *usermem; - size_t size = 10; + size_t size = 128 - KASAN_GRANULE_SIZE; int __maybe_unused unused; kmem = kmalloc(size, GFP_KERNEL); @@ -38,25 +36,25 @@ static noinline void __init copy_user_test(void) } pr_info("out-of-bounds in copy_from_user()\n"); - unused = copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); + unused = copy_from_user(kmem, usermem, size + 1); pr_info("out-of-bounds in copy_to_user()\n"); - unused = copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF); + unused = copy_to_user(usermem, kmem, size + 1); pr_info("out-of-bounds in __copy_from_user()\n"); - unused = __copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); + unused = __copy_from_user(kmem, usermem, size + 1); pr_info("out-of-bounds in __copy_to_user()\n"); - unused = __copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF); + unused = __copy_to_user(usermem, kmem, size + 1); pr_info("out-of-bounds in __copy_from_user_inatomic()\n"); - unused = __copy_from_user_inatomic(kmem, usermem, size + 1 + OOB_TAG_OFF); + unused = __copy_from_user_inatomic(kmem, usermem, size + 1); pr_info("out-of-bounds in __copy_to_user_inatomic()\n"); - unused = __copy_to_user_inatomic(usermem, kmem, size + 1 + OOB_TAG_OFF); + unused = __copy_to_user_inatomic(usermem, kmem, size + 1); pr_info("out-of-bounds in strncpy_from_user()\n"); - unused = strncpy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF); + unused = strncpy_from_user(kmem, usermem, size + 1); vm_munmap((unsigned long)usermem, PAGE_SIZE); kfree(kmem);