https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85230
Bug ID: 85230 Summary: asan: false positives in kernel on allocas Product: gcc Version: 8.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: dvyukov at google dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- We are seeing what looks like false positives related to KASAN alloca instrumentation and interrupt handlers. I don't have full picture yet, but want to document what I know now in case one can spot something obvious in asan.c This is on gcc version 8.0.1 20180301 (experimental) (GCC). Here are 2 examples of presumably false KASAN reports: https://gist.githubusercontent.com/dvyukov/eb7d0edadae48e4a0a2fa751bacb11d7/raw/1b719820c9965168fb8ab281b2fb8b6af63d50b5/gistfile1.txt https://gist.githubusercontent.com/dvyukov/607155ff7a5696cac565975a338f091b/raw/073662fb5f5bfb4893e00a86acbbac9bdf6e1d9b/gistfile1.txt This is on upstream kernel commit 17dec0a949153d9ac00760ba2f5b78cb583e995f. All reports has some similarities, namely: - all happen in interrupt code - when interrupt code accesses pt_regs object which contains saved registers and which is stored on the _task_ stack before switching to interrupt stack - interrupt arrives into __asan_allocas_unpoison function - usually happens inside of crypto_shash_update which contains an alloca, but I suspect it's red herring (we just need a function that uses alloca and there are few of them) This all strongly points in the direction of violated -mno-red-zone (which kernel uses e.g. for interrupts). It seems that saved registers in interrupt entry somehow land onto alloca-ed region which is not yet unpoisoned. Here is disasm of the crypto_shash_update function (you can see 3 alloca-related calls there): https://gist.githubusercontent.com/dvyukov/a55eefef7bb5c305ff4eb91e127524fc/raw/81f2c4d13ae4d46d90a3a6f6c7119a4066ac3a66/gistfile1.txt I thought that maybe code first deallocates the alloca memory on stack, and only then unpoisons it. But no, it first unpoisons and then restores rsp. It's also strange that it always happens inside of __asan_allocas_unpoison and not in crypto_shash_update itself. If anything allocating more frames should divert interrupt handler further from poisoned memory. However, maybe it's a coincidence, or maybe when interrupt arrived right into crypto_shash_update, pt_regs accidentally land in between poisoned regions. Just in case, I've also tried to unpoison more in __asan_allocas_unpoison: void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom) { if (unlikely(!stack_top)) return; + stack_bottom += 64; + stack_top -= 64; if (unlikely(stack_top > stack_bottom)) return; kasan_unpoison_shadow(stack_top, stack_bottom - stack_top); } trying to cross out any off-by-ones. But this does not help.