The below race is observed on the SPF path: pthread1 pthread2 -------- -------- Speculatively enter __pte_map_lock: irq_disable() ............ All seq lock checks are succeeded. ............ ptl = (pmd_page(*pmd))->ptl __vm_munmap(): mmap_write_lock_killable(); (update the seq count) __do_munmap()--> unmap_region()--> free_pgtables()--> .......... free_pte_range(): ptl = pmd_lock() unlock(ptl) pte_free_tlb()--> ......... pgtable_pte_page_dtor(): (Free the pmd_page(page)->ptl to the slab, on which pthread1 still operating on) spin_trylock(ptl) Seq count check fails spin_unlock(): SPIN_BUG() checks are passed kmem_cache_free()--> do_slab_free(): (a) *(ptl + offset) = c->freelist (b) c->freelist = ptl update ptl->owner, owner->cpu (This is use-after-free of the ptl slab object which is corrupting the next pointer,(a), filled by the pthread2 in the cuuren->freelist) Note that when DEBUG_SPINLOCK is not enabled, race won't exist as ALLOC_SPLIT_PTLOCKS is not defined i.e. ptl is stored directly in the page structure. Note that this change as uses smp sync doesn't have any perf impact in the production builds as the intended code is under ALLOC_SPLIT_PTLOCKS which will be absent. Bug: 265837312 Change-Id: I05b11c80a45c285ab8d293cca925aa4388f62d05 Signed-off-by: Charan Teja Kalla <quic_charante@quicinc.com>
160 KiB
160 KiB