aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 17:41:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 17:41:09 -0400
commit7376e39ad96583545faefa2e7798bcb6a2a212a7 (patch)
tree09842932712f06a21a7f1bdd83fa6fbfabc79d70
parentc6503f12d135a616b25be99a492765fc9e9fe07e (diff)
parentdaf5cc27eed99afdea8d96e71b89ba41f5406ef6 (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.c2
-rw-r--r--net/ceph/messenger.c8
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);