Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6285bc23 authored by Alex Elder's avatar Alex Elder
Browse files

ceph: avoid 32-bit page index overflow

A pgoff_t is defined (by default) to have type (unsigned long).  On
architectures such as i686 that's a 32-bit type.  The ceph address
space code was attempting to produce 64 bit offsets by shifting a
page's index by PAGE_CACHE_SHIFT, but the result was not what was
desired because the shift occurred before the result got promoted
to 64 bits.

Fix this by converting all uses of page->index used in this way to
use the page_offset() macro, which ensures the 64-bit result has the
intended value.

This fixes http://tracker.newdream.net/issues/3112



Reported-by: default avatarMohamed Pakkeer <pakkeer.mohideen@realimage.com>
Signed-off-by: default avatarAlex Elder <elder@inktank.com>
Reviewed-by: default avatarSage Weil <sage@inktank.com>
parent 457712a0
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
	dout("readpage inode %p file %p page %p index %lu\n",
	     inode, filp, page, page->index);
	err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
				  page->index << PAGE_CACHE_SHIFT, &len,
				  (u64) page_offset(page), &len,
				  ci->i_truncate_seq, ci->i_truncate_size,
				  &page, 1, 0);
	if (err == -ENOENT)
@@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
	int nr_pages = 0;
	int ret;

	off = page->index << PAGE_CACHE_SHIFT;
	off = (u64) page_offset(page);

	/* count pages */
	next_index = page->index;
@@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
	struct ceph_inode_info *ci;
	struct ceph_fs_client *fsc;
	struct ceph_osd_client *osdc;
	loff_t page_off = page->index << PAGE_CACHE_SHIFT;
	loff_t page_off = page_offset(page);
	int len = PAGE_CACHE_SIZE;
	loff_t i_size;
	int err = 0;
@@ -817,8 +817,7 @@ static int ceph_writepages_start(struct address_space *mapping,
			/* ok */
			if (locked_pages == 0) {
				/* prepare async write request */
				offset = (unsigned long long)page->index
					<< PAGE_CACHE_SHIFT;
				offset = (u64) page_offset(page);
				len = wsize;
				req = ceph_osdc_new_request(&fsc->client->osdc,
					    &ci->i_layout,
@@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
	struct inode *inode = vma->vm_file->f_dentry->d_inode;
	struct page *page = vmf->page;
	struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
	loff_t off = page->index << PAGE_CACHE_SHIFT;
	loff_t off = page_offset(page);
	loff_t size, len;
	int ret;