* [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs [not found] <20190422194205.10404-1-sashal@kernel.org> @ 2019-04-22 19:41 ` Sasha Levin 2019-04-23 8:28 ` Ilya Dryomov 2019-04-22 19:41 ` [PATCH AUTOSEL 5.0 71/98] ceph: fix use-after-free on symlink traversal Sasha Levin 1 sibling, 1 reply; 4+ messages in thread From: Sasha Levin @ 2019-04-22 19:41 UTC (permalink / raw) To: linux-kernel, stable; +Cc: Ilya Dryomov, Sasha Levin, ceph-devel, netdev From: Ilya Dryomov <idryomov@gmail.com> [ Upstream commit 187df76325af5d9e12ae9daec1510307797e54f0 ] A bvec can now consist of multiple physically contiguous pages. This means that bvec_iter_advance() can move to a different page while staying in the same bvec (i.e. ->bi_bvec_done != 0). The messenger works in terms of segments which can now be defined as the smaller of a bvec and a page. The "more bytes to process in this segment" condition holds only if bvec_iter_advance() leaves us in the same bvec _and_ in the same page. On next bvec (possibly in the same page) and on next page (possibly in the same bvec) we may need to set ->last_piece. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> --- net/ceph/messenger.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 7e71b0df1fbc..3083988ce729 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -840,6 +840,7 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, size_t bytes) { struct ceph_bio_iter *it = &cursor->bio_iter; + struct page *page = bio_iter_page(it->bio, it->iter); BUG_ON(bytes > cursor->resid); BUG_ON(bytes > bio_iter_len(it->bio, it->iter)); @@ -851,7 +852,8 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, return false; /* no more data */ } - if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done)) + if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done && + page == bio_iter_page(it->bio, it->iter))) return false; /* more bytes to process in this segment */ if (!it->iter.bi_size) { @@ -899,6 +901,7 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, size_t bytes) { struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; + struct page *page = bvec_iter_page(bvecs, cursor->bvec_iter); BUG_ON(bytes > cursor->resid); BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter)); @@ -910,7 +913,8 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, return false; /* no more data */ } - if (!bytes || cursor->bvec_iter.bi_bvec_done) + if (!bytes || (cursor->bvec_iter.bi_bvec_done && + page == bvec_iter_page(bvecs, cursor->bvec_iter))) return false; /* more bytes to process in this segment */ BUG_ON(cursor->last_piece); -- 2.19.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs 2019-04-22 19:41 ` [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs Sasha Levin @ 2019-04-23 8:28 ` Ilya Dryomov 2019-05-02 12:51 ` Sasha Levin 0 siblings, 1 reply; 4+ messages in thread From: Ilya Dryomov @ 2019-04-23 8:28 UTC (permalink / raw) To: Sasha Levin; +Cc: LKML, stable, Ceph Development, netdev On Mon, Apr 22, 2019 at 9:44 PM Sasha Levin <sashal@kernel.org> wrote: > > From: Ilya Dryomov <idryomov@gmail.com> > > [ Upstream commit 187df76325af5d9e12ae9daec1510307797e54f0 ] > > A bvec can now consist of multiple physically contiguous pages. > This means that bvec_iter_advance() can move to a different page while > staying in the same bvec (i.e. ->bi_bvec_done != 0). > > The messenger works in terms of segments which can now be defined as > the smaller of a bvec and a page. The "more bytes to process in this > segment" condition holds only if bvec_iter_advance() leaves us in the > same bvec _and_ in the same page. On next bvec (possibly in the same > page) and on next page (possibly in the same bvec) we may need to set > ->last_piece. > > Signed-off-by: Ilya Dryomov <idryomov@gmail.com> > Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> > --- > net/ceph/messenger.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c > index 7e71b0df1fbc..3083988ce729 100644 > --- a/net/ceph/messenger.c > +++ b/net/ceph/messenger.c > @@ -840,6 +840,7 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, > size_t bytes) > { > struct ceph_bio_iter *it = &cursor->bio_iter; > + struct page *page = bio_iter_page(it->bio, it->iter); > > BUG_ON(bytes > cursor->resid); > BUG_ON(bytes > bio_iter_len(it->bio, it->iter)); > @@ -851,7 +852,8 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, > return false; /* no more data */ > } > > - if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done)) > + if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done && > + page == bio_iter_page(it->bio, it->iter))) > return false; /* more bytes to process in this segment */ > > if (!it->iter.bi_size) { > @@ -899,6 +901,7 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, > size_t bytes) > { > struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; > + struct page *page = bvec_iter_page(bvecs, cursor->bvec_iter); > > BUG_ON(bytes > cursor->resid); > BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter)); > @@ -910,7 +913,8 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, > return false; /* no more data */ > } > > - if (!bytes || cursor->bvec_iter.bi_bvec_done) > + if (!bytes || (cursor->bvec_iter.bi_bvec_done && > + page == bvec_iter_page(bvecs, cursor->bvec_iter))) > return false; /* more bytes to process in this segment */ > > BUG_ON(cursor->last_piece); Same here, shouldn't be needed. Thanks, Ilya ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs 2019-04-23 8:28 ` Ilya Dryomov @ 2019-05-02 12:51 ` Sasha Levin 0 siblings, 0 replies; 4+ messages in thread From: Sasha Levin @ 2019-05-02 12:51 UTC (permalink / raw) To: Ilya Dryomov; +Cc: LKML, stable, Ceph Development, netdev On Tue, Apr 23, 2019 at 10:28:56AM +0200, Ilya Dryomov wrote: >On Mon, Apr 22, 2019 at 9:44 PM Sasha Levin <sashal@kernel.org> wrote: >> >> From: Ilya Dryomov <idryomov@gmail.com> >> >> [ Upstream commit 187df76325af5d9e12ae9daec1510307797e54f0 ] >> >> A bvec can now consist of multiple physically contiguous pages. >> This means that bvec_iter_advance() can move to a different page while >> staying in the same bvec (i.e. ->bi_bvec_done != 0). >> >> The messenger works in terms of segments which can now be defined as >> the smaller of a bvec and a page. The "more bytes to process in this >> segment" condition holds only if bvec_iter_advance() leaves us in the >> same bvec _and_ in the same page. On next bvec (possibly in the same >> page) and on next page (possibly in the same bvec) we may need to set >> ->last_piece. >> >> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> >> Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> >> --- >> net/ceph/messenger.c | 8 ++++++-- >> 1 file changed, 6 insertions(+), 2 deletions(-) >> >> diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c >> index 7e71b0df1fbc..3083988ce729 100644 >> --- a/net/ceph/messenger.c >> +++ b/net/ceph/messenger.c >> @@ -840,6 +840,7 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, >> size_t bytes) >> { >> struct ceph_bio_iter *it = &cursor->bio_iter; >> + struct page *page = bio_iter_page(it->bio, it->iter); >> >> BUG_ON(bytes > cursor->resid); >> BUG_ON(bytes > bio_iter_len(it->bio, it->iter)); >> @@ -851,7 +852,8 @@ static bool ceph_msg_data_bio_advance(struct ceph_msg_data_cursor *cursor, >> return false; /* no more data */ >> } >> >> - if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done)) >> + if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done && >> + page == bio_iter_page(it->bio, it->iter))) >> return false; /* more bytes to process in this segment */ >> >> if (!it->iter.bi_size) { >> @@ -899,6 +901,7 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, >> size_t bytes) >> { >> struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; >> + struct page *page = bvec_iter_page(bvecs, cursor->bvec_iter); >> >> BUG_ON(bytes > cursor->resid); >> BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter)); >> @@ -910,7 +913,8 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, >> return false; /* no more data */ >> } >> >> - if (!bytes || cursor->bvec_iter.bi_bvec_done) >> + if (!bytes || (cursor->bvec_iter.bi_bvec_done && >> + page == bvec_iter_page(bvecs, cursor->bvec_iter))) >> return false; /* more bytes to process in this segment */ >> >> BUG_ON(cursor->last_piece); > >Same here, shouldn't be needed. Dropped, thanks! ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 5.0 71/98] ceph: fix use-after-free on symlink traversal [not found] <20190422194205.10404-1-sashal@kernel.org> 2019-04-22 19:41 ` [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs Sasha Levin @ 2019-04-22 19:41 ` Sasha Levin 1 sibling, 0 replies; 4+ messages in thread From: Sasha Levin @ 2019-04-22 19:41 UTC (permalink / raw) To: linux-kernel, stable; +Cc: Al Viro, Ilya Dryomov, Sasha Levin, ceph-devel From: Al Viro <viro@zeniv.linux.org.uk> [ Upstream commit daf5cc27eed99afdea8d96e71b89ba41f5406ef6 ] free the symlink body after the same RCU delay we have for freeing the struct inode itself, so that traversal during RCU pathwalk wouldn't step into freed memory. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> --- fs/ceph/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 9d1f34d46627..f7f9e305aaf8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -524,6 +524,7 @@ static void ceph_i_callback(struct rcu_head *head) struct inode *inode = container_of(head, struct inode, i_rcu); struct ceph_inode_info *ci = ceph_inode(inode); + kfree(ci->i_symlink); kmem_cache_free(ceph_inode_cachep, ci); } @@ -561,7 +562,6 @@ void ceph_destroy_inode(struct inode *inode) ceph_put_snap_realm(mdsc, realm); } - kfree(ci->i_symlink); while ((n = rb_first(&ci->i_fragtree)) != NULL) { frag = rb_entry(n, struct ceph_inode_frag, node); rb_erase(n, &ci->i_fragtree); -- 2.19.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-05-02 12:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20190422194205.10404-1-sashal@kernel.org>
2019-04-22 19:41 ` [PATCH AUTOSEL 5.0 61/98] libceph: fix breakage caused by multipage bvecs Sasha Levin
2019-04-23 8:28 ` Ilya Dryomov
2019-05-02 12:51 ` Sasha Levin
2019-04-22 19:41 ` [PATCH AUTOSEL 5.0 71/98] ceph: fix use-after-free on symlink traversal Sasha Levin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox