diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-29 17:41:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-29 17:41:09 -0400 |
commit | 7376e39ad96583545faefa2e7798bcb6a2a212a7 (patch) | |
tree | 09842932712f06a21a7f1bdd83fa6fbfabc79d70 | |
parent | c6503f12d135a616b25be99a492765fc9e9fe07e (diff) | |
parent | daf5cc27eed99afdea8d96e71b89ba41f5406ef6 (diff) |
Merge tag 'ceph-for-5.1-rc3' of git://github.com/ceph/ceph-client
Pull ceph fixes from Ilya Dryomov:
"A patch to avoid choking on multipage bvecs in the messenger and a
small use-after-free fix"
* tag 'ceph-for-5.1-rc3' of git://github.com/ceph/ceph-client:
ceph: fix use-after-free on symlink traversal
libceph: fix breakage caused by multipage bvecs
-rw-r--r-- | fs/ceph/inode.c | 2 | ||||
-rw-r--r-- | net/ceph/messenger.c | 8 |
2 files changed, 7 insertions, 3 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e3346628efe2..2d61ddda9bf5 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -524,6 +524,7 @@ static void ceph_i_callback(struct rcu_head *head) | |||
524 | struct inode *inode = container_of(head, struct inode, i_rcu); | 524 | struct inode *inode = container_of(head, struct inode, i_rcu); |
525 | struct ceph_inode_info *ci = ceph_inode(inode); | 525 | struct ceph_inode_info *ci = ceph_inode(inode); |
526 | 526 | ||
527 | kfree(ci->i_symlink); | ||
527 | kmem_cache_free(ceph_inode_cachep, ci); | 528 | kmem_cache_free(ceph_inode_cachep, ci); |
528 | } | 529 | } |
529 | 530 | ||
@@ -566,7 +567,6 @@ void ceph_destroy_inode(struct inode *inode) | |||
566 | } | 567 | } |
567 | } | 568 | } |
568 | 569 | ||
569 | kfree(ci->i_symlink); | ||
570 | while ((n = rb_first(&ci->i_fragtree)) != NULL) { | 570 | while ((n = rb_first(&ci->i_fragtree)) != NULL) { |
571 | frag = rb_entry(n, struct ceph_inode_frag, node); | 571 | frag = rb_entry(n, struct ceph_inode_frag, node); |
572 | rb_erase(n, &ci->i_fragtree); | 572 | rb_erase(n, &ci->i_fragtree); |
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, | |||
840 | size_t bytes) | 840 | size_t bytes) |
841 | { | 841 | { |
842 | struct ceph_bio_iter *it = &cursor->bio_iter; | 842 | struct ceph_bio_iter *it = &cursor->bio_iter; |
843 | struct page *page = bio_iter_page(it->bio, it->iter); | ||
843 | 844 | ||
844 | BUG_ON(bytes > cursor->resid); | 845 | BUG_ON(bytes > cursor->resid); |
845 | BUG_ON(bytes > bio_iter_len(it->bio, it->iter)); | 846 | 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, | |||
851 | return false; /* no more data */ | 852 | return false; /* no more data */ |
852 | } | 853 | } |
853 | 854 | ||
854 | if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done)) | 855 | if (!bytes || (it->iter.bi_size && it->iter.bi_bvec_done && |
856 | page == bio_iter_page(it->bio, it->iter))) | ||
855 | return false; /* more bytes to process in this segment */ | 857 | return false; /* more bytes to process in this segment */ |
856 | 858 | ||
857 | if (!it->iter.bi_size) { | 859 | if (!it->iter.bi_size) { |
@@ -899,6 +901,7 @@ static bool ceph_msg_data_bvecs_advance(struct ceph_msg_data_cursor *cursor, | |||
899 | size_t bytes) | 901 | size_t bytes) |
900 | { | 902 | { |
901 | struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; | 903 | struct bio_vec *bvecs = cursor->data->bvec_pos.bvecs; |
904 | struct page *page = bvec_iter_page(bvecs, cursor->bvec_iter); | ||
902 | 905 | ||
903 | BUG_ON(bytes > cursor->resid); | 906 | BUG_ON(bytes > cursor->resid); |
904 | BUG_ON(bytes > bvec_iter_len(bvecs, cursor->bvec_iter)); | 907 | 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, | |||
910 | return false; /* no more data */ | 913 | return false; /* no more data */ |
911 | } | 914 | } |
912 | 915 | ||
913 | if (!bytes || cursor->bvec_iter.bi_bvec_done) | 916 | if (!bytes || (cursor->bvec_iter.bi_bvec_done && |
917 | page == bvec_iter_page(bvecs, cursor->bvec_iter))) | ||
914 | return false; /* more bytes to process in this segment */ | 918 | return false; /* more bytes to process in this segment */ |
915 | 919 | ||
916 | BUG_ON(cursor->last_piece); | 920 | BUG_ON(cursor->last_piece); |