does software KASAN not instrument READ_ONCE() on arm64 with LTO?

Marco Elver elver at google.com
Fri Mar 28 09:58:57 PDT 2025


On Thu, 27 Mar 2025 at 20:10, 'Jann Horn' via kasan-dev
<kasan-dev at googlegroups.com> wrote:
>
> On Thu, Mar 27, 2025 at 8:29 AM Alexander Potapenko <glider at google.com> wrote:
> > On Thu, Mar 27, 2025 at 12:10 AM Jann Horn <jannh at google.com> wrote:
> > > Hi!
> > >
> > > I just realized - arm64 redefines __READ_ONCE() to use inline assembly
> > > instead of a volatile load, and ASAN is designed to not instrument asm
> > > statement operands (not even memory operands).
> >
> > Nice catch!
> >
> > > (I think I may have a years-old LLVM patch somewhere that changes
> > > that, but I vaguely recall being told once that that's an intentional
> > > design decision. I might be misremembering that though...)
> >
> > We have some best-effort asm instrumentation in KMSAN (see
> > https://llvm.org/doxygen/MemorySanitizer_8cpp_source.html#l04968) and
> > could potentially do something similar for KASAN, but if I remember
> > correctly there were some corner cases with unknown argument sizes and
> > with percpu instrumentation (at least on x86 percpu accesses receive
> > an offset of the variable in .data..percpu, not the actual address).
>
> Ah, I see. Annoying that memory operands are used for that...
>
> > > So because __READ_ONCE() does not call anything like
> > > instrument_read(), I think instrumentation-based KASAN in LTO arm64
> > > builds probably doesn't cover READ_ONCE() accesses?
> > >
> > > A quick test seems to confirm this: https://godbolt.org/z/8oYfaExYf
> >
> > So should it be enough to call instrument_read()?
>
> Sort of, I think; but I'm not sure whether instrument_read() is
> available in this header or whether that would create an include
> dependency loop because READ_ONCE is so fundamental
> (linux/instrumented.h depends on linux/compiler.h, which pulls in
> asm/rwonce.h). So instrument_read() might maybe need to be open-coded
> if we want to use it here? IDK...
>
> And also I think this would probably cause ASAN false-positives in
> __read_once_word_nocheck(), because I think disabling ASAN
> instrumentation per-function with __no_sanitize_or_inline probably
> does not disable explicit instrumentation through instrument_read()?

Correct, the attribute doesn't kill explicit instrumentation.

Easiest way to "fix" this is to disable the promotion to acquire by
arm64 when built with a *compiler-based* (i.e. not KASAN_HWTAGS)
sanitizer + LTO. This promotion was only made because of fear of
overaggressive compiler optimizations with LTO. If there's a bug due
to the compiler breaking dependency ordering [1], it'd actually be
very nice to see a sanitizer splat, but I doubt we'd ever be so lucky.

[1] https://lpc.events/event/16/contributions/1174/attachments/1108/2121/Status%20Report%20-%20Broken%20Dependency%20Orderings%20in%20the%20Linux%20Kernel.pdf



More information about the linux-arm-kernel mailing list