lkml.org 
[lkml]   [2020]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 214/265] erofs: fix partially uninitialized misuse in z_erofs_onlinepage_fixup
    Date
    From: Gao Xiang <hsiangkao@redhat.com>

    commit 3c597282887fd55181578996dca52ce697d985a5 upstream.

    Hongyu reported "id != index" in z_erofs_onlinepage_fixup() with
    specific aarch64 environment easily, which wasn't shown before.

    After digging into that, I found that high 32 bits of page->private
    was set to 0xaaaaaaaa rather than 0 (due to z_erofs_onlinepage_init
    behavior with specific compiler options). Actually we only use low
    32 bits to keep the page information since page->private is only 4
    bytes on most 32-bit platforms. However z_erofs_onlinepage_fixup()
    uses the upper 32 bits by mistake.

    Let's fix it now.

    Reported-and-tested-by: Hongyu Jin <hongyu.jin@unisoc.com>
    Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support")
    Cc: <stable@vger.kernel.org> # 4.19+
    Reviewed-by: Chao Yu <yuchao0@huawei.com>
    Link: https://lore.kernel.org/r/20200618234349.22553-1-hsiangkao@aol.com
    Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/erofs/zdata.h | 20 ++++++++++----------
    1 file changed, 10 insertions(+), 10 deletions(-)

    diff --git a/fs/erofs/zdata.h b/fs/erofs/zdata.h
    index 7824f5563a552..9b66c28b3ae9d 100644
    --- a/fs/erofs/zdata.h
    +++ b/fs/erofs/zdata.h
    @@ -144,22 +144,22 @@ static inline void z_erofs_onlinepage_init(struct page *page)
    static inline void z_erofs_onlinepage_fixup(struct page *page,
    uintptr_t index, bool down)
    {
    - unsigned long *p, o, v, id;
    -repeat:
    - p = &page_private(page);
    - o = READ_ONCE(*p);
    + union z_erofs_onlinepage_converter u = { .v = &page_private(page) };
    + int orig, orig_index, val;

    - id = o >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT;
    - if (id) {
    +repeat:
    + orig = atomic_read(u.o);
    + orig_index = orig >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT;
    + if (orig_index) {
    if (!index)
    return;

    - DBG_BUGON(id != index);
    + DBG_BUGON(orig_index != index);
    }

    - v = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) |
    - ((o & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned int)down);
    - if (cmpxchg(p, o, v) != o)
    + val = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) |
    + ((orig & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned int)down);
    + if (atomic_cmpxchg(u.o, orig, val) != orig)
    goto repeat;
    }

    --
    2.25.1
    \
     
     \ /
      Last update: 2020-06-30 00:10    [W:3.666 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site