On Tue, Feb 13, 2024 at 4:40 AM Benjamin Gray <bgray@xxxxxxxxxxxxx> wrote: > > 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 <bgray@xxxxxxxxxxxxx> > > --- > > I am interested in removing the need for kasan_arch_is_ready() entirely, > as it mostly acts like a separate check of kasan_enabled(). Dropping kasan_arch_is_ready() calls from KASAN internals and instead relying on kasan_enabled() checks in include/linux/kasan.h would be great! I filed a bug about this a while ago: https://bugzilla.kernel.org/show_bug.cgi?id=217049 > 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(). Sounds good to me. I would also go through the list of other exported KASAN functions to check whether any of them also need a kasan_enabled() check. At least kasan_unpoison_task_stack() seems to be one of them. > 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, We can also add something like CONFIG_ARCH_HAS_KASAN_FLAG_ENABLE and only use a static branch only on those architectures where it's required. > but I did have to add another > patch for an uninitialised data access it introduces. What was this data access? Is this something we need to fix in the mainline? > On the other hand, KASAN does more than shadow based sanitisation, so > we'd be disabling that in early boot too. I think the things that we need to handle before KASAN is enabled is kasan_cache_create() and kasan_metadata_size() (if these can even called before KASAN is enabled). Otherwise, KASAN just collects metadata, which is useless without shadow memory-based reporting anyway. > --- > 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 > For the patch itself as a fix: Reviewed-by: Andrey Konovalov <andreyknvl@xxxxxxxxx> Thanks!