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, 04 Aug 2014 18:06:42 -0700
From:	"Darrick J. Wong" <darrick.wong@...cle.com>
To:	tytso@....edu, darrick.wong@...cle.com
Cc:	linux-ext4@...r.kernel.org
Subject: [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline
 directories

If we encounter a directory whose i_size != the inline data size, just
set i_size to the size of the inline data.  The pb.last_block
calculation is wrong since pb.last_block == -1, which results in
i_size being set to zero, which corrupts the directory.

Clear the inline_data inode flag if we actually /are/ setting i_size
to zero.

Signed-off-by: Darrick J. Wong <darrick.wong@...cle.com>
---
 e2fsck/pass1.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index b214f72..1a9e0d5 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -2832,17 +2832,21 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		if (inode->i_flags & EXT4_INLINE_DATA_FL) {
 			int flags;
 			size_t size;
+			errcode_t err;
 
+			size = 0;
 			flags = ctx->fs->flags;
 			ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
-			if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
-				bad_size = 5;
+			err = ext2fs_inline_data_size(ctx->fs, pctx->ino,
+						      &size);
 			ctx->fs->flags = (flags &
 					  EXT2_FLAG_IGNORE_CSUM_ERRORS) |
 					 (ctx->fs->flags &
 					  ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
-			if (size != inode->i_size)
-				bad_size = 5;
+			if (err || size != inode->i_size) {
+				bad_size = 7;
+				pctx->num = size;
+			}
 		} else if (inode->i_size & (fs->blocksize - 1))
 			bad_size = 5;
 		else if (nblock > (pb.last_block + 1))
@@ -2875,12 +2879,20 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	}
 	/* i_size for symlinks is checked elsewhere */
 	if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
-		pctx->num = (pb.last_block+1) * fs->blocksize;
+		/* Did inline_data set pctx->num earlier? */
+		if (bad_size != 7)
+			pctx->num = (pb.last_block + 1) * fs->blocksize;
 		pctx->group = bad_size;
 		if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
 			if (LINUX_S_ISDIR(inode->i_mode))
 				pctx->num &= 0xFFFFFFFFULL;
 			ext2fs_inode_size_set(fs, inode, pctx->num);
+			if (EXT2_I_SIZE(inode) == 0 &&
+			    (inode->i_flags & EXT4_INLINE_DATA_FL)) {
+				memset(inode->i_block, 0,
+				       sizeof(inode->i_block));
+				inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+			}
 			dirty_inode++;
 		}
 		pctx->num = 0;

--
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