lkml.org 
[lkml]   [2019]   [Aug]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 062/158] lib/scatterlist: Fix mapping iterator when sg->offset is greater than PAGE_SIZE
    Date
    From: Christophe Leroy <christophe.leroy@c-s.fr>

    commit aeb87246537a83c2aff482f3f34a2e0991e02cbc upstream.

    All mapping iterator logic is based on the assumption that sg->offset
    is always lower than PAGE_SIZE.

    But there are situations where sg->offset is such that the SG item
    is on the second page. In that case sg_copy_to_buffer() fails
    properly copying the data into the buffer. One of the reason is
    that the data will be outside the kmapped area used to access that
    data.

    This patch fixes the issue by adjusting the mapping iterator
    offset and pgoffset fields such that offset is always lower than
    PAGE_SIZE.

    Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
    Fixes: 4225fc8555a9 ("lib/scatterlist: use page iterator in the mapping iterator")
    Cc: stable@vger.kernel.org
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    lib/scatterlist.c | 9 +++++----
    1 file changed, 5 insertions(+), 4 deletions(-)

    --- a/lib/scatterlist.c
    +++ b/lib/scatterlist.c
    @@ -496,17 +496,18 @@ static bool sg_miter_get_next_page(struc
    {
    if (!miter->__remaining) {
    struct scatterlist *sg;
    - unsigned long pgoffset;

    if (!__sg_page_iter_next(&miter->piter))
    return false;

    sg = miter->piter.sg;
    - pgoffset = miter->piter.sg_pgoffset;

    - miter->__offset = pgoffset ? 0 : sg->offset;
    + miter->__offset = miter->piter.sg_pgoffset ? 0 : sg->offset;
    + miter->piter.sg_pgoffset += miter->__offset >> PAGE_SHIFT;
    + miter->__offset &= PAGE_SIZE - 1;
    miter->__remaining = sg->offset + sg->length -
    - (pgoffset << PAGE_SHIFT) - miter->__offset;
    + (miter->piter.sg_pgoffset << PAGE_SHIFT) -
    + miter->__offset;
    miter->__remaining = min_t(unsigned long, miter->__remaining,
    PAGE_SIZE - miter->__offset);
    }

    \
     
     \ /
      Last update: 2019-08-02 11:39    [W:5.813 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site