From 9dcc7a0baa00a8b5535f70f1ca4a31e460de0ea2 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 10 Feb 2017 23:39:25 -0500 Subject: [PATCH] add patch dont-crash-when-truncating-encrypted-on-the-orphan-list --- ...sh-when-truncating-encrypted-on-the-orphan-list | 92 ++++++++++++++++++++++ series | 1 + timestamps | 15 ++-- 3 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 dont-crash-when-truncating-encrypted-on-the-orphan-list diff --git a/dont-crash-when-truncating-encrypted-on-the-orphan-list b/dont-crash-when-truncating-encrypted-on-the-orphan-list new file mode 100644 index 00000000..99dbb927 --- /dev/null +++ b/dont-crash-when-truncating-encrypted-on-the-orphan-list @@ -0,0 +1,92 @@ +ext4: don't BUG when truncating encrypted inodes on the orphan list + +Fix a BUG when the kernel tries to mount a file system constructed as +follows: + +echo foo > foo.txt +mke2fs -Fq -t ext4 -O encrypt foo.img 100 +debugfs -w foo.img << EOF +write foo.txt a +set_inode_field a i_flags 0x80800 +set_super_value s_last_orphan 12 +quit +EOF + +root@kvm-xfstests:~# mount -o loop foo.img /mnt +[ 160.238770] ------------[ cut here ]------------ +[ 160.240106] kernel BUG at /usr/projects/linux/ext4/fs/ext4/inode.c:3874! +[ 160.240106] invalid opcode: 0000 [#1] SMP +[ 160.240106] Modules linked in: +[ 160.240106] CPU: 0 PID: 2547 Comm: mount Tainted: G W 4.10.0-rc3-00034-gcdd33b941b67 #227 +[ 160.240106] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1 04/01/2014 +[ 160.240106] task: f4518000 task.stack: f47b6000 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 +[ 160.240106] EFLAGS: 00010246 CPU: 0 +[ 160.240106] EAX: 00000001 EBX: f7be4b50 ECX: f47b7dc0 EDX: 00000007 +[ 160.240106] ESI: f43b05a8 EDI: f43babec EBP: f47b7dd0 ESP: f47b7dac +[ 160.240106] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 +[ 160.240106] CR0: 80050033 CR2: bfd85b08 CR3: 34a00680 CR4: 000006f0 +[ 160.240106] Call Trace: +[ 160.240106] ext4_truncate+0x1e9/0x3e5 +[ 160.240106] ext4_fill_super+0x286f/0x2b1e +[ 160.240106] ? set_blocksize+0x2e/0x7e +[ 160.240106] mount_bdev+0x114/0x15f +[ 160.240106] ext4_mount+0x15/0x17 +[ 160.240106] ? ext4_calculate_overhead+0x39d/0x39d +[ 160.240106] mount_fs+0x58/0x115 +[ 160.240106] vfs_kern_mount+0x4b/0xae +[ 160.240106] do_mount+0x671/0x8c3 +[ 160.240106] ? _copy_from_user+0x70/0x83 +[ 160.240106] ? strndup_user+0x31/0x46 +[ 160.240106] SyS_mount+0x57/0x7b +[ 160.240106] do_int80_syscall_32+0x4f/0x61 +[ 160.240106] entry_INT80_32+0x2f/0x2f +[ 160.240106] EIP: 0xb76b919e +[ 160.240106] EFLAGS: 00000246 CPU: 0 +[ 160.240106] EAX: ffffffda EBX: 08053838 ECX: 08052188 EDX: 080537e8 +[ 160.240106] ESI: c0ed0000 EDI: 00000000 EBP: 080537e8 ESP: bfa13660 +[ 160.240106] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b +[ 160.240106] Code: 59 8b 00 a8 01 0f 84 09 01 00 00 8b 07 66 25 00 f0 66 3d 00 80 75 61 89 f8 e8 3e e2 ff ff 84 c0 74 56 83 bf 48 02 00 00 00 75 02 <0f> 0b 81 7d e8 00 10 00 00 74 02 0f 0b 8b 43 04 8b 53 08 31 c9 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 SS:ESP: 0068:f47b7dac +[ 160.317241] ---[ end trace d6a773a375c810a5 ]--- + +The problem is that when the kernel tries to truncate an inode in +ext4_truncate(), it tries to clear any on-disk data beyond i_size. +Without the encryption key, it can't do that, and so it triggers a +BUG. + +E2fsck does *not* provide this service, and in practice most file +systems have their orphan list processed by e2fsck, so to avoid +crashing, this patch skips this step if we don't have access to the +encryption key (which is the case when processing the orphan list; in +all other cases, we will have the encryption key, or the kernel +wouldn't have allowed the file to be opened). + +An open question is whether the fact that e2fsck isn't clearing the +bytes beyond i_size causing problems --- and if we've lived with it +not doing it for so long, can we drop this from the kernel replay of +the orphan list in all cases (not just when we don't have the key for +encrypted inodes). + +Addresses-Google-Bug: #35209576 + +Signed-off-by: Theodore Ts'o +--- + fs/ext4/inode.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index bc282f9d0969..831d025e59ad 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3944,6 +3944,10 @@ static int ext4_block_truncate_page(handle_t *handle, + unsigned blocksize; + struct inode *inode = mapping->host; + ++ /* If we are processing an encrypted inode during orphan list handling */ ++ if (!fscrypt_has_encryption_key(inode)) ++ return 0; ++ + blocksize = inode->i_sb->s_blocksize; + length = blocksize - (offset & (blocksize - 1)); + diff --git a/series b/series index 9705c928..e056114b 100644 --- a/series +++ b/series @@ -27,6 +27,7 @@ dax-assert-that-i_rw_sem-is-held-exclusive-for-writes fix-stripe-unaligned-allocations do-not-use-stripe-width-if-it-is-not-set +dont-crash-when-truncating-encrypted-on-the-orphan-list #################################################### # unstable patches diff --git a/timestamps b/timestamps index 0813a539..779ff75d 100755 --- a/timestamps +++ b/timestamps @@ -45,9 +45,6 @@ touch -d @1485131749 propagate-error-values-from-ext4_inline_data_truncate touch -d @1485131752 replace-bug-on-with-warn-on-in-mb_find_extent touch -d @1485545670 trim-allocation-requests-to-group-size touch -d @1485545738 fix-data-corruption-in-data_journal-mode -touch -d @1485545858 stable-boundary-undo.patch -touch -d @1485545918 add-support-for-log-metadata-block-tracking-in-log -touch -d @1485545978 add-indirection-to-metadata-block-read-paths touch -d @1485546038 cleaner touch -d @1485546098 disable-writeback touch -d @1485974942 save-patch @@ -61,13 +58,17 @@ touch -d @1486268059 dont-leak-modified-metadata-buffers-on-an-aborted-journal touch -d @1486269486 preserve-needs_recovery-flag-when-journal-is-aborted touch -d @1486276008 return-erofs-for-recovery-when-device-readonly touch -d @1486276068 rename-s_resize_flags-to-s_ext4_flags -touch -d @1486276071 stable-boundary touch -d @1486276128 add_shutdown_flag touch -d @1486342034 add-shutdown-ioctl touch -d @1486582767 fix-dax-write-locking touch -d @1486582993 dax-assert-that-i_rw_sem-is-held-exclusive-for-writes touch -d @1486705856 fix-stripe-unaligned-allocations touch -d @1486706169 do-not-use-stripe-width-if-it-is-not-set -touch -d @1486706202 series -touch -d @1486706207 status -touch -d @1486706235 timestamps +touch -d @1486706229 stable-boundary +touch -d @1486706289 stable-boundary-undo.patch +touch -d @1486763957 add-support-for-log-metadata-block-tracking-in-log +touch -d @1486769699 add-indirection-to-metadata-block-read-paths +touch -d @1486780771 series +touch -d @1486783145 dont-crash-when-truncating-encrypted-on-the-orphan-list +touch -d @1486783145 status +touch -d @1486787954 timestamps -- 2.11.4.GIT