release_free_meta() accesses the shadow directly through the path
kasan_slab_free
__kasan_slab_free
kasan_release_object_meta
release_free_meta
kasan_mem_to_shadow
There are no kasan_arch_is_ready() guards here, allowing an oops when
the shadow is not initialized. The oops can be seen on a Power8 KVM
guest.
This patch adds the guard to release_free_meta(), as it's the first
level that specifically requires the shadow.
It is safe to put the guard at the start of this function, before the
stack put: only kasan_save_free_info() can initialize the saved stack,
which itself is guarded with kasan_arch_is_ready() by its caller
poison_slab_object(). If the arch becomes ready before
release_free_meta() then we will not observe KASAN_SLAB_FREE_META in the
object's shadow, so we will not put an uninitialized stack either.
Signed-off-by: Benjamin Gray <
bg...@linux.ibm.com>
---
I am interested in removing the need for kasan_arch_is_ready() entirely,
as it mostly acts like a separate check of kasan_enabled(). Currently
both are necessary, but I think adding a kasan_enabled() guard to
check_region_inline() makes kasan_enabled() a superset of
kasan_arch_is_ready().
Allowing an arch to override kasan_enabled() can then let us replace it
with a static branch that we enable somewhere in boot (for PowerPC,
after we use a bunch of generic code to parse the device tree to
determine how we want to configure the MMU). This should generally work
OK I think, as HW tags already does this, but I did have to add another
patch for an uninitialised data access it introduces.
On the other hand, KASAN does more than shadow based sanitisation, so
we'd be disabling that in early boot too.
---
mm/kasan/generic.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index df6627f62402..032bf3e98c24 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -522,6 +522,9 @@ static void release_alloc_meta(struct kasan_alloc_meta *meta)
static void release_free_meta(const void *object, struct kasan_free_meta *meta)
{
+ if (!kasan_arch_is_ready())
+ return;
+
/* Check if free meta is valid. */
if (*(u8 *)kasan_mem_to_shadow(object) != KASAN_SLAB_FREE_META)
return;
--
2.43.0