No subject
Thu Aug 7 06:00:02 AEST 2025
>
> Ok, we will have the **only** check kasan_enabled() then in
> kasan-enabled.h which
>
> #if defined(CONFIG_ARCH_DEFER_KASAN) || defined(CONFIG_KASAN_HW_TAGS)
> static __always_inline bool kasan_enabled(void)
> {
> return static_branch_likely(&kasan_flag_enabled);
> }
> #else
> static inline bool kasan_enabled(void)
> {
> return IS_ENABLED(CONFIG_KASAN);
> }
>
> And will remove kasan_arch_is_ready (current kasan_shadow_initialized in v4).
>
> So it is the single place to check if KASAN is enabled for all arch
> and internal KASAN code.
> Same behavior is in the current mainline code but only for HW_TAGS.
>
> Is this correct?
>
Yep, that's what I meant.
>>
>>
>>> {
>>> return static_branch_likely(&kasan_flag_enabled);
>>> }
>>>
>>> -static inline bool kasan_hw_tags_enabled(void)
>>> +static inline void kasan_enable(void)
>>> +{
>>> + static_branch_enable(&kasan_flag_enabled);
>>> +}
>>> +#else
>>> +/* For architectures that can enable KASAN early, use compile-time check. */
>>> +static __always_inline bool kasan_shadow_initialized(void)
>>> {
>>> return kasan_enabled();
>>> }
>>>
>>
>> ...
>>
>>>
>>> void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
>>> -int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
>>> -void kasan_release_vmalloc(unsigned long start, unsigned long end,
>>> +
>>> +int __kasan_populate_vmalloc(unsigned long addr, unsigned long size);
>>> +static inline int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
>>> +{
>>> + if (!kasan_shadow_initialized())
>>> + return 0;
>>
>>
>> What's the point of moving these checks to header?
>> Leave it in C, it's easier to grep and navigate code this way.
>
> Andrey Konovalov had comments [1] to avoid checks in C
> by moving them to headers under __wrappers.
>
> : 1. Avoid spraying kasan_arch_is_ready() throughout the KASAN
> : implementation and move these checks into include/linux/kasan.h (and
> : add __wrappers when required).
>
> [1] https://lore.kernel.org/all/CA+fCnZcGyTECP15VMSPh+duLmxNe=ApHfOnbAY3NqtFHZvceZw@mail.gmail.com/
>
I think Andrey K. meant cases when we have multiple implementations of one function for each mode.
In such case it makes sense to merge multiple kasan_arch_is_ready() checks into one in the header.
But in case like with kasan_populate_vmalloc() we have only one implementation so I don't see any
value in adding wrapper/moving to header.
>>
>>
>>> + return __kasan_populate_vmalloc(addr, size);
>>> +}
>>> +
>>> +void __kasan_release_vmalloc(unsigned long start, unsigned long end,
>>> unsigned long free_region_start,
>>> unsigned long free_region_end,
>>> unsigned long flags);
>>> +static inline void kasan_release_vmalloc(unsigned long start,
>>> + unsigned long end,
>>> + unsigned long free_region_start,
>>> + unsigned long free_region_end,
>>> + unsigned long flags)
>>> +{
>>> + if (kasan_shadow_initialized())
>>> + __kasan_release_vmalloc(start, end, free_region_start,
>>> + free_region_end, flags);
>>> +}
>>>
>>
>> ...> @@ -250,7 +259,7 @@ static inline void poison_slab_object(struct kmem_cache *cache, void *object,
>>> bool __kasan_slab_pre_free(struct kmem_cache *cache, void *object,
>>> unsigned long ip)
>>> {
>>> - if (!kasan_arch_is_ready() || is_kfence_address(object))
>>> + if (is_kfence_address(object))
>>> return false;
>>> return check_slab_allocation(cache, object, ip);
>>> }
>>> @@ -258,7 +267,7 @@ bool __kasan_slab_pre_free(struct kmem_cache *cache, void *object,
>>> bool __kasan_slab_free(struct kmem_cache *cache, void *object, bool init,
>>> bool still_accessible)
>>> {
>>> - if (!kasan_arch_is_ready() || is_kfence_address(object))
>>> + if (is_kfence_address(object))
>>> return false;
>>>
>>> poison_slab_object(cache, object, init, still_accessible);
>>> @@ -282,9 +291,6 @@ bool __kasan_slab_free(struct kmem_cache *cache, void *object, bool init,
>>>
>>> static inline bool check_page_allocation(void *ptr, unsigned long ip)
>>> {
>>> - if (!kasan_arch_is_ready())
>>> - return false;
>>> -
>>
>>
>> Well, you can't do this yet, because no arch using ARCH_DEFER_KASAN yet, so this breaks
>> bisectability.
>> Leave it, and remove with separate patch only when there are no users left.
>
> Will do in v5 at the end of patch series.
>
>>
>>> if (ptr != page_address(virt_to_head_page(ptr))) {
>>> kasan_report_invalid_free(ptr, ip, KASAN_REPORT_INVALID_FREE);
>>> return true;
>>> @@ -511,7 +517,7 @@ bool __kasan_mempool_poison_object(void *ptr, unsigned long ip)
>>> return true;
>>> }
>>>
>>> - if (is_kfence_address(ptr) || !kasan_arch_is_ready())
>>> + if (is_kfence_address(ptr))
>>> return true;
>>>
>>> slab = folio_slab(folio);
>>
>>
More information about the Linuxppc-dev
mailing list