lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 28 Nov 2011 16:31:46 -0800
From:	"Darrick J. Wong" <djwong@...ibm.com>
To:	Andreas Dilger <adilger.kernel@...ger.ca>,
	Theodore Tso <tytso@....edu>,
	"Darrick J. Wong" <djwong@...ibm.com>
Cc:	Sunil Mushran <sunil.mushran@...cle.com>,
	Amir Goldstein <amir73il@...il.com>,
	Andi Kleen <andi@...stfloor.org>,
	Mingming Cao <cmm@...ibm.com>,
	Joel Becker <jlbec@...lplan.org>, linux-ext4@...r.kernel.org,
	Coly Li <colyli@...il.com>
Subject: [PATCH 33/50] libext2fs: Use i_generation in inode-related metadata
	checksums

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@...ibm.com>
---
 lib/ext2fs/csum.c  |   45 +++++++++++++++++++++++++++++++++++++++------
 lib/ext2fs/mkdir.c |    8 +++++---
 2 files changed, 44 insertions(+), 9 deletions(-)


diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index e033453..c47cbf0 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -72,7 +72,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;
 	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
@@ -82,14 +83,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:
 	return retval;
 }
 
@@ -249,15 +257,23 @@ 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;
+
+	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;
 
+out:
 	return retval;
 }
 
@@ -311,16 +327,23 @@ 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, old_csum;
+	__u32 ncrc, old_csum, gen;
+	struct ext2_inode inode;
 
 	size = count_offset + (count * sizeof(struct ext2_dx_entry));
 	old_csum = t->checksum;
 	t->checksum = 0;
 
+	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);
 	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)t,
 				sizeof(struct ext2_dx_tail));
@@ -328,6 +351,7 @@ static errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum,
 
 	*crc = ncrc;
 
+out:
 	return retval;
 }
 
@@ -431,19 +455,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;
 }
 
@@ -588,7 +619,7 @@ static errcode_t ext2fs_inode_csum(ext2_filsys fs, ext2_ino_t inum,
 			       struct ext2_inode_large *inode,
 			       __u32 *crc, int has_hi)
 {
-	__u32 ncrc;
+	__u32 ncrc, gen;
 	struct ext2_inode_large *desc = inode;
 	size_t size = fs->super->s_inode_size;
 	__u16 old_lo;
@@ -603,9 +634,11 @@ static errcode_t ext2fs_inode_csum(ext2_filsys fs, ext2_ino_t inum,
 	}
 
 	inum = ext2fs_cpu_to_le32(inum);
+	gen = 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..cb1e5a7 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -93,12 +93,14 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	inode.i_size = fs->blocksize;
 
 	/*
-	 * Write out the inode and inode data block
+	 * Write out the inode and inode data block.  The inode generation
+	 * number is assigned by write_new_inode, which means that the
+	 * call to write_dir_block must come after it.
 	 */
-	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;
 

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

Powered by blists - more mailing lists