lkml.org 
[lkml]   [2019]   [Aug]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.2 047/131] mm/z3fold: dont try to use buddy slots after free
    Date
    [ Upstream commit bb9a374dfa3a2f46581455ab66cd1d24c5e3d183 ]

    As reported by Henry Burns:

    Running z3fold stress testing with address sanitization showed zhdr->slots
    was being used after it was freed.

    z3fold_free(z3fold_pool, handle)
    free_handle(handle)
    kmem_cache_free(pool->c_handle, zhdr->slots)
    release_z3fold_page_locked_list(kref)
    __release_z3fold_page(zhdr, true)
    zhdr_to_pool(zhdr)
    slots_to_pool(zhdr->slots) *BOOM*

    To fix this, add pointer to the pool back to z3fold_header and modify
    zhdr_to_pool to return zhdr->pool.

    Link: http://lkml.kernel.org/r/20190708134808.e89f3bfadd9f6ffd7eff9ba9@gmail.com
    Fixes: 7c2b8baa61fe ("mm/z3fold.c: add structure for buddy handles")
    Signed-off-by: Vitaly Wool <vitalywool@gmail.com>
    Reported-by: Henry Burns <henryburns@google.com>
    Reviewed-by: Shakeel Butt <shakeelb@google.com>
    Cc: Jonathan Adams <jwadams@google.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    mm/z3fold.c | 5 ++++-
    1 file changed, 4 insertions(+), 1 deletion(-)

    diff --git a/mm/z3fold.c b/mm/z3fold.c
    index dfcd69d08c1e9..304f2883cdb93 100644
    --- a/mm/z3fold.c
    +++ b/mm/z3fold.c
    @@ -101,6 +101,7 @@ struct z3fold_buddy_slots {
    * @refcount: reference count for the z3fold page
    * @work: work_struct for page layout optimization
    * @slots: pointer to the structure holding buddy slots
    + * @pool: pointer to the containing pool
    * @cpu: CPU which this page "belongs" to
    * @first_chunks: the size of the first buddy in chunks, 0 if free
    * @middle_chunks: the size of the middle buddy in chunks, 0 if free
    @@ -114,6 +115,7 @@ struct z3fold_header {
    struct kref refcount;
    struct work_struct work;
    struct z3fold_buddy_slots *slots;
    + struct z3fold_pool *pool;
    short cpu;
    unsigned short first_chunks;
    unsigned short middle_chunks;
    @@ -320,6 +322,7 @@ static struct z3fold_header *init_z3fold_page(struct page *page,
    zhdr->start_middle = 0;
    zhdr->cpu = -1;
    zhdr->slots = slots;
    + zhdr->pool = pool;
    INIT_LIST_HEAD(&zhdr->buddy);
    INIT_WORK(&zhdr->work, compact_page_work);
    return zhdr;
    @@ -426,7 +429,7 @@ static enum buddy handle_to_buddy(unsigned long handle)

    static inline struct z3fold_pool *zhdr_to_pool(struct z3fold_header *zhdr)
    {
    - return slots_to_pool(zhdr->slots);
    + return zhdr->pool;
    }

    static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked)
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-08-05 15:56    [W:4.573 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site