Patchwork [32/47] libext2fs: Use i_generation in inode-related metadata checksums

login
register
mail settings
Submitter Darrick J. Wong
Date Oct. 8, 2011, 7:36 a.m.
Message ID <20111008073640.17888.74853.stgit@elm3c44.beaverton.ibm.com>
Download mbox | patch
Permalink /patch/118458/
State Superseded
Headers show

Comments

Darrick J. Wong - Oct. 8, 2011, 7:36 a.m.
Whenever we are calculating a checksum for a piece of metadata that is
associated with an inode, incorporate i_generation into that calculation so
that old metadata blocks cannot be re-associated after a delete/create cycle.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
 lib/ext2fs/csum.c  |   45 +++++++++++++++++++++++++++++++++++++--------
 lib/ext2fs/mkdir.c |    4 ++--
 2 files changed, 39 insertions(+), 10 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index d89fa37..e2c32f4 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -71,7 +71,8 @@  static errcode_t ext2fs_ext_attr_block_csum(ext2_filsys fs, ext2_ino_t inum,
 {
 	errcode_t retval = 0;
 	char *buf = (char *)hdr;
-	__u32 ncrc, old_crc = hdr->h_checksum;
+	__u32 gen, ncrc, old_crc = hdr->h_checksum;
+	struct ext2_inode inode;
 
 	hdr->h_checksum = 0;
 #ifdef WORDS_BIGENDIAN
@@ -88,14 +89,21 @@  static errcode_t ext2fs_ext_attr_block_csum(ext2_filsys fs, ext2_ino_t inum,
 		ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&block,
 					sizeof(block));
 	} else {
+		retval = ext2fs_read_inode(fs, inum, &inode);
+		if (retval)
+			goto out;
 		inum = ext2fs_cpu_to_le32(inum);
+		gen = ext2fs_cpu_to_le32(inode.i_generation);
 		ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum,
 					sizeof(inum));
+		ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&gen,
+					sizeof(gen));
 	}
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)buf, fs->blocksize);
 	hdr->h_checksum = old_crc;
 	*crc = ncrc;
 
+out:
 #ifdef WORDS_BIGENDIAN
 	ext2fs_free_mem(&buf);
 #endif
@@ -190,7 +198,8 @@  static errcode_t ext2fs_dirent_csum(ext2_filsys fs, ext2_ino_t inum,
 {
 	errcode_t retval = 0;
 	char *buf = (char *)dirent;
-	__u32 ncrc;
+	__u32 ncrc, gen;
+	struct ext2_inode inode;
 
 #ifdef WORDS_BIGENDIAN
 	retval = ext2fs_get_mem(fs->blocksize, &buf);
@@ -202,15 +211,20 @@  static errcode_t ext2fs_dirent_csum(ext2_filsys fs, ext2_ino_t inum,
 		goto out;
 #endif
 
+	retval = ext2fs_read_inode(fs, inum, &inode);
+	if (retval)
+		goto out;
 	inum = ext2fs_cpu_to_le32(inum);
+	gen = ext2fs_cpu_to_le32(inode.i_generation);
 	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
 				sizeof(fs->super->s_uuid));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum, sizeof(inum));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&gen, sizeof(gen));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)buf, size);
 	*crc = ncrc;
 
-#ifdef WORDS_BIGENDIAN
 out:
+#ifdef WORDS_BIGENDIAN
 	ext2fs_free_mem(&buf);
 #endif
 
@@ -270,7 +284,8 @@  static errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum,
 	errcode_t retval = 0;
 	char *buf = (char *)dirent;
 	int size;
-	__u32 ncrc;
+	__u32 ncrc, gen;
+	struct ext2_inode inode;
 
 	size = count_offset + (count * sizeof(struct ext2_dx_entry));
 
@@ -289,15 +304,20 @@  static errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum,
 		goto out;
 #endif
 
+	retval = ext2fs_read_inode(fs, inum, &inode);
+	if (retval)
+		goto out;
 	inum = ext2fs_cpu_to_le32(inum);
+	gen = ext2fs_cpu_to_le32(inode.i_generation);
 	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
 				sizeof(fs->super->s_uuid));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum, sizeof(inum));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&gen, sizeof(gen));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)buf, size);
 	*crc = ncrc;
 
-#ifdef WORDS_BIGENDIAN
 out:
+#ifdef WORDS_BIGENDIAN
 	ext2fs_free_mem(&buf);
 #endif
 
@@ -409,19 +429,26 @@  static errcode_t ext2fs_extent_block_csum(ext2_filsys fs, ext2_ino_t inum,
 					  __u32 *crc)
 {
 	int size;
-	__u32 ncrc;
-	errcode_t retval = 0;
+	__u32 ncrc, gen;
+	errcode_t retval;
+	struct ext2_inode inode;
 
 	size = EXT3_EXTENT_TAIL_OFFSET(eh) + offsetof(struct ext3_extent_tail,
 						      et_checksum);
 
+	retval = ext2fs_read_inode(fs, inum, &inode);
+	if (retval)
+		goto out;
 	inum = ext2fs_cpu_to_le32(inum);
+	gen = ext2fs_cpu_to_le32(inode.i_generation);
 	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
 			       sizeof(fs->super->s_uuid));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum, sizeof(inum));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&gen, sizeof(gen));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)eh, size);
 	*crc = ncrc;
 
+out:
 	return retval;
 }
 
@@ -566,7 +593,7 @@  static errcode_t ext2fs_inode_csum(ext2_filsys fs, ext2_ino_t inum,
 			       struct ext2_inode_large *inode,
 			       __u32 *crc)
 {
-	__u32 ncrc;
+	__u32 ncrc, gen;
 	struct ext2_inode_large *desc = inode;
 	size_t size = fs->super->s_inode_size;
 	__u16 old_lo;
@@ -594,9 +621,11 @@  static errcode_t ext2fs_inode_csum(ext2_filsys fs, ext2_ino_t inum,
 #endif
 
 	inum = ext2fs_cpu_to_le32(inum);
+	gen = ext2fs_cpu_to_le32(inode->i_generation);
 	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
 				sizeof(fs->super->s_uuid));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum, sizeof(inum));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&gen, sizeof(gen));
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)desc, size);
 	*crc = ncrc;
 
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index 0d1b7b8..e4c7d05 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -95,10 +95,10 @@  errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	/*
 	 * Write out the inode and inode data block
 	 */
-	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
+	retval = ext2fs_write_new_inode(fs, ino, &inode);
 	if (retval)
 		goto cleanup;
-	retval = ext2fs_write_new_inode(fs, ino, &inode);
+	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
 	if (retval)
 		goto cleanup;