* [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
* [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
* 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
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