linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] hfsplus: fix overflow in hfsplus_get_block
@ 2011-02-15 13:14 Christoph Hellwig
  2011-02-15 13:14 ` [PATCH 2/3] hfsplus: fix overflow in hfsplus_read_wrapper Christoph Hellwig
  2011-02-15 13:14 ` [PATCH 2/3] hfsplus: lift the 2TB size limit Christoph Hellwig
  0 siblings, 2 replies; 3+ messages in thread
From: Christoph Hellwig @ 2011-02-15 13:14 UTC (permalink / raw)
  To: linux-fsdevel

For filesystems larger than 2TB the final sector number passed to
map_bh might overflow the range representable in a 32-bit data type.
Make sure we use a sector_t for it and the arithmetics calculating it.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>

Index: linux-2.6/fs/hfsplus/extents.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/extents.c	2011-02-15 13:42:05.456421843 +0100
+++ linux-2.6/fs/hfsplus/extents.c	2011-02-15 13:42:41.667422001 +0100
@@ -209,6 +209,7 @@ int hfsplus_get_block(struct inode *inod
 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
 	int res = -EIO;
 	u32 ablock, dblock, mask;
+	sector_t sector;
 	int was_dirty = 0;
 	int shift;
 
@@ -255,10 +256,12 @@ int hfsplus_get_block(struct inode *inod
 done:
 	dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n",
 		inode->i_ino, (long long)iblock, dblock);
+
 	mask = (1 << sbi->fs_shift) - 1;
-	map_bh(bh_result, sb,
-		(dblock << sbi->fs_shift) + sbi->blockoffset +
-			(iblock & mask));
+	sector = ((sector_t)dblock << sbi->fs_shift) +
+		  sbi->blockoffset + (iblock & mask);
+	map_bh(bh_result, sb, sector);
+
 	if (create) {
 		set_buffer_new(bh_result);
 		hip->phys_size += sb->s_blocksize;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/3] hfsplus: fix overflow in hfsplus_read_wrapper
  2011-02-15 13:14 [PATCH 1/3] hfsplus: fix overflow in hfsplus_get_block Christoph Hellwig
@ 2011-02-15 13:14 ` Christoph Hellwig
  2011-02-15 13:14 ` [PATCH 2/3] hfsplus: lift the 2TB size limit Christoph Hellwig
  1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2011-02-15 13:14 UTC (permalink / raw)
  To: linux-fsdevel

For partitions larger than 2TB or at such an offset the hfs wrapper code
in hfsplus might overflow the range representable in a 32-bit
data type. Make sure we use a sector_t for the arithmetics leading to it.

I'm not sure this code can be readed at all as hfs itself never supported
such large volumes.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>

Index: linux-2.6/fs/hfsplus/wrapper.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/wrapper.c	2011-02-15 13:42:59.676423416 +0100
+++ linux-2.6/fs/hfsplus/wrapper.c	2011-02-15 13:43:40.711164800 +0100
@@ -169,8 +169,9 @@ reread:
 		if (!hfsplus_read_mdb(sbi->s_vhdr, &wd))
 			goto out_free_backup_vhdr;
 		wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
-		part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
-		part_size = wd.embed_count * wd.ablk_size;
+		part_start += (sector_t)wd.ablk_start +
+			       (sector_t)wd.embed_start * wd.ablk_size;
+		part_size = (sector_t)wd.embed_count * wd.ablk_size;
 		goto reread;
 	default:
 		/*

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/3] hfsplus: lift the 2TB size limit
  2011-02-15 13:14 [PATCH 1/3] hfsplus: fix overflow in hfsplus_get_block Christoph Hellwig
  2011-02-15 13:14 ` [PATCH 2/3] hfsplus: fix overflow in hfsplus_read_wrapper Christoph Hellwig
@ 2011-02-15 13:14 ` Christoph Hellwig
  1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2011-02-15 13:14 UTC (permalink / raw)
  To: linux-fsdevel

Replace the hardcoded 2TB limit with a dynamic limit based on the block
size now that we have fixed the few overflows preventing operation
with large volumes.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>

Index: linux-2.6/fs/hfsplus/super.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/super.c	2011-02-15 13:45:06.292423835 +0100
+++ linux-2.6/fs/hfsplus/super.c	2011-02-15 13:54:53.598943828 +0100
@@ -393,6 +393,13 @@ static int hfsplus_fill_super(struct sup
 	if (!sbi->rsrc_clump_blocks)
 		sbi->rsrc_clump_blocks = 1;
 
+	err = generic_check_addressable(sbi->alloc_blksz_shift,
+					sbi->total_blocks);
+	if (err) {
+		printk(KERN_ERR "hfs: filesystem size too large.\n");
+		goto out_free_vhdr;
+	}
+
 	/* Set up operations so we can load metadata */
 	sb->s_op = &hfsplus_sops;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
@@ -417,6 +424,8 @@ static int hfsplus_fill_super(struct sup
 		sb->s_flags |= MS_RDONLY;
 	}
 
+	err = -EINVAL;
+
 	/* Load metadata objects (B*Trees) */
 	sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
 	if (!sbi->ext_tree) {
Index: linux-2.6/fs/hfsplus/wrapper.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/wrapper.c	2011-02-15 13:44:44.208420508 +0100
+++ linux-2.6/fs/hfsplus/wrapper.c	2011-02-15 13:45:03.883421555 +0100
@@ -138,10 +138,6 @@ int hfsplus_read_wrapper(struct super_bl
 
 	if (hfsplus_get_last_session(sb, &part_start, &part_size))
 		goto out;
-	if ((u64)part_start + part_size > 0x100000000ULL) {
-		pr_err("hfs: volumes larger than 2TB are not supported yet\n");
-		goto out;
-	}
 
 	error = -ENOMEM;
 	sbi->s_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-02-15 13:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-15 13:14 [PATCH 1/3] hfsplus: fix overflow in hfsplus_get_block Christoph Hellwig
2011-02-15 13:14 ` [PATCH 2/3] hfsplus: fix overflow in hfsplus_read_wrapper Christoph Hellwig
2011-02-15 13:14 ` [PATCH 2/3] hfsplus: lift the 2TB size limit Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).