From: Al Viro <viro@ZenIV.linux.org.uk>
To: linux-block@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Jens Axboe <axboe@kernel.dk>,
Christoph Hellwig <hch@lst.de>,
Vitaly Mayatskikh <v.mayatskih@gmail.com>
Subject: Re: [PATCH] fix unbalanced page refcounting in bio_map_user_iov
Date: Sun, 24 Sep 2017 15:27:39 +0100 [thread overview]
Message-ID: <20170924142739.GS32076@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20170923203323.GR32076@ZenIV.linux.org.uk>
On Sat, Sep 23, 2017 at 09:33:23PM +0100, Al Viro wrote:
> On Sat, Sep 23, 2017 at 06:19:26PM +0100, Al Viro wrote:
> > On Sat, Sep 23, 2017 at 05:55:37PM +0100, Al Viro wrote:
> >
> > > IOW, the loop on failure exit should go through the bio, like __bio_unmap_user()
> > > does. We *also* need to put everything left unused in pages[], but only from the
> > > last iteration through iov_for_each().
> > >
> > > Frankly, I would prefer to reuse the pages[], rather than append to it on each
> > > iteration. Used iov_iter_get_pages_alloc(), actually.
> >
> > Something like completely untested diff below, perhaps...
>
> > + unsigned n = PAGE_SIZE - offs;
> > + unsigned prev_bi_vcnt = bio->bi_vcnt;
>
> Sorry, that should've been followed by
> if (n > bytes)
> n = bytes;
>
> Anyway, a carved-up variant is in vfs.git#work.iov_iter. It still needs
> review and testing; the patch Vitaly has posted in this thread plus 6
> followups, hopefully more readable than aggregate diff.
>
> Comments?
BTW, there's something fishy in bio_copy_user_iov(). If the area we'd asked for
had been too large for a single bio, we are going to create a bio and have
bio_add_pc_page() eventually fill it up to limit. Then we return into
__blk_rq_map_user_iov(), advance iter and call bio_copy_user_iov() again.
Fine, but... now we might have non-zero iter->iov_offset. And this
bmd->is_our_pages = map_data ? 0 : 1;
memcpy(bmd->iov, iter->iov, sizeof(struct iovec) * iter->nr_segs);
iov_iter_init(&bmd->iter, iter->type, bmd->iov,
iter->nr_segs, iter->count);
does not even look at iter->iov_offset. As the result, when it gets to
bio_uncopy_user(), we copy the data from each bio into the *beginning* of
the user area, overwriting that from the other bio.
At the very least, we need bmd->iter = *iter; bmd->iter.iov = bmd->iov;
instead of that iov_iter_init() in there. I'm not sure how far back does
it go; looks like "block: support large requests in blk_rq_map_user_iov"
is the earliest possible point, but it might need more digging to make
sure. v4.5+, if that's when the problems began...
Anyway, I'd added the obvious fix to #work.iov_iter, reordered it and
force-pushed the result.
next prev parent reply other threads:[~2017-09-24 14:27 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-22 5:18 [PATCH] fix unbalanced page refcounting in bio_map_user_iov Vitaly Mayatskikh
2017-09-22 5:24 ` Vitaly Mayatskikh
2017-09-23 16:39 ` Al Viro
2017-09-23 16:55 ` Al Viro
2017-09-23 17:19 ` Al Viro
2017-09-23 20:33 ` Al Viro
2017-09-24 14:27 ` Al Viro [this message]
2017-09-24 17:15 ` Al Viro
2017-09-25 1:48 ` Vitaly Mayatskikh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170924142739.GS32076@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=v.mayatskih@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.