lkml.org 
[lkml]   [2017]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 095/105] more bio_map_user_iov() leak fixes
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Al Viro <viro@zeniv.linux.org.uk>

    commit 2b04e8f6bbb196cab4b232af0f8d48ff2c7a8058 upstream.

    we need to take care of failure exit as well - pages already
    in bio should be dropped by analogue of bio_unmap_pages(),
    since their refcounts had been bumped only once per reference
    in bio.

    Cc: stable@vger.kernel.org
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    Fixed conflicts.
    Intended for v4.4.y. Does not apply to v3.18.y or older kernels.

    block/bio.c | 14 +++++++++-----
    1 file changed, 9 insertions(+), 5 deletions(-)

    --- a/block/bio.c
    +++ b/block/bio.c
    @@ -1268,6 +1268,7 @@ struct bio *bio_map_user_iov(struct requ
    int ret, offset;
    struct iov_iter i;
    struct iovec iov;
    + struct bio_vec *bvec;

    iov_for_each(iov, i, *iter) {
    unsigned long uaddr = (unsigned long) iov.iov_base;
    @@ -1312,7 +1313,12 @@ struct bio *bio_map_user_iov(struct requ
    ret = get_user_pages_fast(uaddr, local_nr_pages,
    (iter->type & WRITE) != WRITE,
    &pages[cur_page]);
    - if (ret < local_nr_pages) {
    + if (unlikely(ret < local_nr_pages)) {
    + for (j = cur_page; j < page_limit; j++) {
    + if (!pages[j])
    + break;
    + put_page(pages[j]);
    + }
    ret = -EFAULT;
    goto out_unmap;
    }
    @@ -1374,10 +1380,8 @@ struct bio *bio_map_user_iov(struct requ
    return bio;

    out_unmap:
    - for (j = 0; j < nr_pages; j++) {
    - if (!pages[j])
    - break;
    - page_cache_release(pages[j]);
    + bio_for_each_segment_all(bvec, bio, j) {
    + put_page(bvec->bv_page);
    }
    out:
    kfree(pages);

    \
     
     \ /
      Last update: 2017-12-15 11:22    [W:4.044 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site