kasan: fix random seed generation for tag-based mode [Linux 5.0]

kasan: fix random seed generation for tag-based mode [Linux 5.0]

This Linux kernel change "kasan: fix random seed generation for tag-based mode" is included in the Linux 5.0 release. This change is authored by Andrey Konovalov <andreyknvl [at] google.com> on Wed Feb 20 22:20:15 2019 -0800. The commit for this change in Linux stable tree is 3f41b60 (patch).

kasan: fix random seed generation for tag-based mode

There are two issues with assigning random percpu seeds right now:

1. We use for_each_possible_cpu() to iterate over cpus, but cpumask is
   not set up yet at the moment of kasan_init(), and thus we only set
   the seed for cpu #0.

2. A call to get_random_u32() always returns the same number and produces
   a message in dmesg, since the random subsystem is not yet initialized.

Fix 1 by calling kasan_init_tags() after cpumask is set up.

Fix 2 by using get_cycles() instead of get_random_u32(). This gives us
lower quality random numbers, but it's good enough, as KASAN is meant to
be used as a debugging tool and not a mitigation.

Link: http://lkml.kernel.org/r/1f8[email protected]google.com
Signed-off-by: Andrey Konovalov <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Alexander Potapenko <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>

There are 7 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/arm64/kernel/setup.c  | 3 +++
 arch/arm64/mm/kasan_init.c | 2 --
 mm/kasan/tags.c            | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index d09ec76f..0098493 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -339,6 +339,9 @@ void __init setup_arch(char **cmdline_p)
    smp_init_cpus();
    smp_build_mpidr_hash();

+   /* Init percpu seeds for random tags after cpus are set up. */
+   kasan_init_tags();
+
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
    /*
     * Make sure init_thread_info.ttbr0 always generates translation
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4b55b15..f37a86d 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -252,8 +252,6 @@ void __init kasan_init(void)
    memset(kasan_early_shadow_page, KASAN_SHADOW_INIT, PAGE_SIZE);
    cpu_replace_ttbr1(lm_alias(swapper_pg_dir));

-   kasan_init_tags();
-
    /* At this point kasan is fully initialized. Enable error messages */
    init_task.kasan_depth = 0;
    pr_info("KernelAddressSanitizer initialized\n");
diff --git a/mm/kasan/tags.c b/mm/kasan/tags.c
index 0777649..63fca31 100644
--- a/mm/kasan/tags.c
+++ b/mm/kasan/tags.c
@@ -46,7 +46,7 @@ void kasan_init_tags(void)
    int cpu;

    for_each_possible_cpu(cpu)
-       per_cpu(prng_state, cpu) = get_random_u32();
+       per_cpu(prng_state, cpu) = (u32)get_cycles();
 }

 /*

Leave a Reply

Your email address will not be published. Required fields are marked *