While working address sanitizer for kernel I've discovered use-after-free bug in __put_anon_vma. For the last anon_vma, anon_vma->root freed before child anon_vma. Later in anon_vma_free(anon_vma) we are referencing to already freed anon_vma->root to check rwsem. This patch puts freeing of child anon_vma before freeing of anon_vma->root.
Cc: sta...@vger.kernel.org # v3.0+ Signed-off-by: Andrey Ryabinin <a.ryabi...@samsung.com> --- mm/rmap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 9c3e773..161bffc7 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1564,10 +1564,11 @@ void __put_anon_vma(struct anon_vma *anon_vma) { struct anon_vma *root = anon_vma->root; - if (root != anon_vma && atomic_dec_and_test(&root->refcount)) + if (root != anon_vma && atomic_dec_and_test(&root->refcount)) { + anon_vma_free(anon_vma); anon_vma_free(root); - - anon_vma_free(anon_vma); + } else + anon_vma_free(anon_vma); } static struct anon_vma *rmap_walk_anon_lock(struct page *page, -- 1.8.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/