aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-17 03:13:47 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-17 03:13:47 -0400
commitad3273d5f1b99d7319a986ab568dcbde2f9e53dd (patch)
tree157e5b5b5c8a32500f98991f216b2082183e62c3
parentc0747ad363fff90c2edf490fc089e3ae0920b410 (diff)
parentcce6c9f7e6029caee45c459db5b3e78fec6973cb (diff)
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Ted writes: Various ext4 bug fixes; primarily making ext4 more robust against maliciously crafted file systems, and some DAX fixes. * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4, dax: set ext4_dax_aops for dax files ext4, dax: add ext4_bmap to ext4_dax_aops ext4: don't mark mmp buffer head dirty ext4: show test_dummy_encryption mount option in /proc/mounts ext4: close race between direct IO and ext4_break_layouts() ext4: fix online resizing for bigalloc file systems with a 1k block size ext4: fix online resize's handling of a too-small final block group ext4: recalucate superblock checksum after updating free blocks/inodes ext4: avoid arithemetic overflow that can trigger a BUG ext4: avoid divide by zero fault when deleting corrupted inline directories ext4: check to make sure the rename(2)'s destination is not freed ext4: add nonstring annotations to ext4.h
-rw-r--r--fs/ext4/dir.c20
-rw-r--r--fs/ext4/ext4.h20
-rw-r--r--fs/ext4/inline.c4
-rw-r--r--fs/ext4/inode.c20
-rw-r--r--fs/ext4/mmp.c1
-rw-r--r--fs/ext4/namei.c6
-rw-r--r--fs/ext4/resize.c23
-rw-r--r--fs/ext4/super.c4
8 files changed, 72 insertions, 26 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index e2902d394f1b..f93f9881ec18 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -76,7 +76,7 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
76 else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len))) 76 else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
77 error_msg = "rec_len is too small for name_len"; 77 error_msg = "rec_len is too small for name_len";
78 else if (unlikely(((char *) de - buf) + rlen > size)) 78 else if (unlikely(((char *) de - buf) + rlen > size))
79 error_msg = "directory entry across range"; 79 error_msg = "directory entry overrun";
80 else if (unlikely(le32_to_cpu(de->inode) > 80 else if (unlikely(le32_to_cpu(de->inode) >
81 le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))) 81 le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
82 error_msg = "inode out of bounds"; 82 error_msg = "inode out of bounds";
@@ -85,18 +85,16 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
85 85
86 if (filp) 86 if (filp)
87 ext4_error_file(filp, function, line, bh->b_blocknr, 87 ext4_error_file(filp, function, line, bh->b_blocknr,
88 "bad entry in directory: %s - offset=%u(%u), " 88 "bad entry in directory: %s - offset=%u, "
89 "inode=%u, rec_len=%d, name_len=%d", 89 "inode=%u, rec_len=%d, name_len=%d, size=%d",
90 error_msg, (unsigned) (offset % size), 90 error_msg, offset, le32_to_cpu(de->inode),
91 offset, le32_to_cpu(de->inode), 91 rlen, de->name_len, size);
92 rlen, de->name_len);
93 else 92 else
94 ext4_error_inode(dir, function, line, bh->b_blocknr, 93 ext4_error_inode(dir, function, line, bh->b_blocknr,
95 "bad entry in directory: %s - offset=%u(%u), " 94 "bad entry in directory: %s - offset=%u, "
96 "inode=%u, rec_len=%d, name_len=%d", 95 "inode=%u, rec_len=%d, name_len=%d, size=%d",
97 error_msg, (unsigned) (offset % size), 96 error_msg, offset, le32_to_cpu(de->inode),
98 offset, le32_to_cpu(de->inode), 97 rlen, de->name_len, size);
99 rlen, de->name_len);
100 98
101 return 1; 99 return 1;
102} 100}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0f0edd1cd0cd..caff935fbeb8 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -43,6 +43,17 @@
43#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION) 43#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
44#include <linux/fscrypt.h> 44#include <linux/fscrypt.h>
45 45
46#include <linux/compiler.h>
47
48/* Until this gets included into linux/compiler-gcc.h */
49#ifndef __nonstring
50#if defined(GCC_VERSION) && (GCC_VERSION >= 80000)
51#define __nonstring __attribute__((nonstring))
52#else
53#define __nonstring
54#endif
55#endif
56
46/* 57/*
47 * The fourth extended filesystem constants/structures 58 * The fourth extended filesystem constants/structures
48 */ 59 */
@@ -675,6 +686,9 @@ enum {
675/* Max physical block we can address w/o extents */ 686/* Max physical block we can address w/o extents */
676#define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF 687#define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF
677 688
689/* Max logical block we can support */
690#define EXT4_MAX_LOGICAL_BLOCK 0xFFFFFFFF
691
678/* 692/*
679 * Structure of an inode on the disk 693 * Structure of an inode on the disk
680 */ 694 */
@@ -1226,7 +1240,7 @@ struct ext4_super_block {
1226 __le32 s_feature_ro_compat; /* readonly-compatible feature set */ 1240 __le32 s_feature_ro_compat; /* readonly-compatible feature set */
1227/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ 1241/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */
1228/*78*/ char s_volume_name[16]; /* volume name */ 1242/*78*/ char s_volume_name[16]; /* volume name */
1229/*88*/ char s_last_mounted[64]; /* directory where last mounted */ 1243/*88*/ char s_last_mounted[64] __nonstring; /* directory where last mounted */
1230/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ 1244/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */
1231 /* 1245 /*
1232 * Performance hints. Directory preallocation should only 1246 * Performance hints. Directory preallocation should only
@@ -1277,13 +1291,13 @@ struct ext4_super_block {
1277 __le32 s_first_error_time; /* first time an error happened */ 1291 __le32 s_first_error_time; /* first time an error happened */
1278 __le32 s_first_error_ino; /* inode involved in first error */ 1292 __le32 s_first_error_ino; /* inode involved in first error */
1279 __le64 s_first_error_block; /* block involved of first error */ 1293 __le64 s_first_error_block; /* block involved of first error */
1280 __u8 s_first_error_func[32]; /* function where the error happened */ 1294 __u8 s_first_error_func[32] __nonstring; /* function where the error happened */
1281 __le32 s_first_error_line; /* line number where error happened */ 1295 __le32 s_first_error_line; /* line number where error happened */
1282 __le32 s_last_error_time; /* most recent time of an error */ 1296 __le32 s_last_error_time; /* most recent time of an error */
1283 __le32 s_last_error_ino; /* inode involved in last error */ 1297 __le32 s_last_error_ino; /* inode involved in last error */
1284 __le32 s_last_error_line; /* line number where error happened */ 1298 __le32 s_last_error_line; /* line number where error happened */
1285 __le64 s_last_error_block; /* block involved of last error */ 1299 __le64 s_last_error_block; /* block involved of last error */
1286 __u8 s_last_error_func[32]; /* function where the error happened */ 1300 __u8 s_last_error_func[32] __nonstring; /* function where the error happened */
1287#define EXT4_S_ERR_END offsetof(struct ext4_super_block, s_mount_opts) 1301#define EXT4_S_ERR_END offsetof(struct ext4_super_block, s_mount_opts)
1288 __u8 s_mount_opts[64]; 1302 __u8 s_mount_opts[64];
1289 __le32 s_usr_quota_inum; /* inode for tracking user quota */ 1303 __le32 s_usr_quota_inum; /* inode for tracking user quota */
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 3543fe80a3c4..7b4736022761 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1753,6 +1753,7 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
1753{ 1753{
1754 int err, inline_size; 1754 int err, inline_size;
1755 struct ext4_iloc iloc; 1755 struct ext4_iloc iloc;
1756 size_t inline_len;
1756 void *inline_pos; 1757 void *inline_pos;
1757 unsigned int offset; 1758 unsigned int offset;
1758 struct ext4_dir_entry_2 *de; 1759 struct ext4_dir_entry_2 *de;
@@ -1780,8 +1781,9 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
1780 goto out; 1781 goto out;
1781 } 1782 }
1782 1783
1784 inline_len = ext4_get_inline_size(dir);
1783 offset = EXT4_INLINE_DOTDOT_SIZE; 1785 offset = EXT4_INLINE_DOTDOT_SIZE;
1784 while (offset < dir->i_size) { 1786 while (offset < inline_len) {
1785 de = ext4_get_inline_entry(dir, &iloc, offset, 1787 de = ext4_get_inline_entry(dir, &iloc, offset,
1786 &inline_pos, &inline_size); 1788 &inline_pos, &inline_size);
1787 if (ext4_check_dir_entry(dir, NULL, de, 1789 if (ext4_check_dir_entry(dir, NULL, de,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d0dd585add6a..d767e993591d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3413,12 +3413,16 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
3413{ 3413{
3414 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 3414 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
3415 unsigned int blkbits = inode->i_blkbits; 3415 unsigned int blkbits = inode->i_blkbits;
3416 unsigned long first_block = offset >> blkbits; 3416 unsigned long first_block, last_block;
3417 unsigned long last_block = (offset + length - 1) >> blkbits;
3418 struct ext4_map_blocks map; 3417 struct ext4_map_blocks map;
3419 bool delalloc = false; 3418 bool delalloc = false;
3420 int ret; 3419 int ret;
3421 3420
3421 if ((offset >> blkbits) > EXT4_MAX_LOGICAL_BLOCK)
3422 return -EINVAL;
3423 first_block = offset >> blkbits;
3424 last_block = min_t(loff_t, (offset + length - 1) >> blkbits,
3425 EXT4_MAX_LOGICAL_BLOCK);
3422 3426
3423 if (flags & IOMAP_REPORT) { 3427 if (flags & IOMAP_REPORT) {
3424 if (ext4_has_inline_data(inode)) { 3428 if (ext4_has_inline_data(inode)) {
@@ -3948,6 +3952,7 @@ static const struct address_space_operations ext4_dax_aops = {
3948 .writepages = ext4_dax_writepages, 3952 .writepages = ext4_dax_writepages,
3949 .direct_IO = noop_direct_IO, 3953 .direct_IO = noop_direct_IO,
3950 .set_page_dirty = noop_set_page_dirty, 3954 .set_page_dirty = noop_set_page_dirty,
3955 .bmap = ext4_bmap,
3951 .invalidatepage = noop_invalidatepage, 3956 .invalidatepage = noop_invalidatepage,
3952}; 3957};
3953 3958
@@ -4192,9 +4197,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
4192 return 0; 4197 return 0;
4193} 4198}
4194 4199
4195static void ext4_wait_dax_page(struct ext4_inode_info *ei, bool *did_unlock) 4200static void ext4_wait_dax_page(struct ext4_inode_info *ei)
4196{ 4201{
4197 *did_unlock = true;
4198 up_write(&ei->i_mmap_sem); 4202 up_write(&ei->i_mmap_sem);
4199 schedule(); 4203 schedule();
4200 down_write(&ei->i_mmap_sem); 4204 down_write(&ei->i_mmap_sem);
@@ -4204,14 +4208,12 @@ int ext4_break_layouts(struct inode *inode)
4204{ 4208{
4205 struct ext4_inode_info *ei = EXT4_I(inode); 4209 struct ext4_inode_info *ei = EXT4_I(inode);
4206 struct page *page; 4210 struct page *page;
4207 bool retry;
4208 int error; 4211 int error;
4209 4212
4210 if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem))) 4213 if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
4211 return -EINVAL; 4214 return -EINVAL;
4212 4215
4213 do { 4216 do {
4214 retry = false;
4215 page = dax_layout_busy_page(inode->i_mapping); 4217 page = dax_layout_busy_page(inode->i_mapping);
4216 if (!page) 4218 if (!page)
4217 return 0; 4219 return 0;
@@ -4219,8 +4221,8 @@ int ext4_break_layouts(struct inode *inode)
4219 error = ___wait_var_event(&page->_refcount, 4221 error = ___wait_var_event(&page->_refcount,
4220 atomic_read(&page->_refcount) == 1, 4222 atomic_read(&page->_refcount) == 1,
4221 TASK_INTERRUPTIBLE, 0, 0, 4223 TASK_INTERRUPTIBLE, 0, 0,
4222 ext4_wait_dax_page(ei, &retry)); 4224 ext4_wait_dax_page(ei));
4223 } while (error == 0 && retry); 4225 } while (error == 0);
4224 4226
4225 return error; 4227 return error;
4226} 4228}
@@ -4895,6 +4897,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4895 * not initialized on a new filesystem. */ 4897 * not initialized on a new filesystem. */
4896 } 4898 }
4897 ei->i_flags = le32_to_cpu(raw_inode->i_flags); 4899 ei->i_flags = le32_to_cpu(raw_inode->i_flags);
4900 ext4_set_inode_flags(inode);
4898 inode->i_blocks = ext4_inode_blocks(raw_inode, ei); 4901 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
4899 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo); 4902 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
4900 if (ext4_has_feature_64bit(sb)) 4903 if (ext4_has_feature_64bit(sb))
@@ -5041,7 +5044,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
5041 goto bad_inode; 5044 goto bad_inode;
5042 } 5045 }
5043 brelse(iloc.bh); 5046 brelse(iloc.bh);
5044 ext4_set_inode_flags(inode);
5045 5047
5046 unlock_new_inode(inode); 5048 unlock_new_inode(inode);
5047 return inode; 5049 return inode;
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index 39b07c2d3384..2305b4374fd3 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -49,7 +49,6 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
49 */ 49 */
50 sb_start_write(sb); 50 sb_start_write(sb);
51 ext4_mmp_csum_set(sb, mmp); 51 ext4_mmp_csum_set(sb, mmp);
52 mark_buffer_dirty(bh);
53 lock_buffer(bh); 52 lock_buffer(bh);
54 bh->b_end_io = end_buffer_write_sync; 53 bh->b_end_io = end_buffer_write_sync;
55 get_bh(bh); 54 get_bh(bh);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 116ff68c5bd4..377d516c475f 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3478,6 +3478,12 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3478 int credits; 3478 int credits;
3479 u8 old_file_type; 3479 u8 old_file_type;
3480 3480
3481 if (new.inode && new.inode->i_nlink == 0) {
3482 EXT4_ERROR_INODE(new.inode,
3483 "target of rename is already freed");
3484 return -EFSCORRUPTED;
3485 }
3486
3481 if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT)) && 3487 if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT)) &&
3482 (!projid_eq(EXT4_I(new_dir)->i_projid, 3488 (!projid_eq(EXT4_I(new_dir)->i_projid,
3483 EXT4_I(old_dentry->d_inode)->i_projid))) 3489 EXT4_I(old_dentry->d_inode)->i_projid)))
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index e5fb38451a73..ebbc663d0798 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -19,6 +19,7 @@
19 19
20int ext4_resize_begin(struct super_block *sb) 20int ext4_resize_begin(struct super_block *sb)
21{ 21{
22 struct ext4_sb_info *sbi = EXT4_SB(sb);
22 int ret = 0; 23 int ret = 0;
23 24
24 if (!capable(CAP_SYS_RESOURCE)) 25 if (!capable(CAP_SYS_RESOURCE))
@@ -29,7 +30,7 @@ int ext4_resize_begin(struct super_block *sb)
29 * because the user tools have no way of handling this. Probably a 30 * because the user tools have no way of handling this. Probably a
30 * bad time to do it anyways. 31 * bad time to do it anyways.
31 */ 32 */
32 if (EXT4_SB(sb)->s_sbh->b_blocknr != 33 if (EXT4_B2C(sbi, sbi->s_sbh->b_blocknr) !=
33 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { 34 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
34 ext4_warning(sb, "won't resize using backup superblock at %llu", 35 ext4_warning(sb, "won't resize using backup superblock at %llu",
35 (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); 36 (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
@@ -1986,6 +1987,26 @@ retry:
1986 } 1987 }
1987 } 1988 }
1988 1989
1990 /*
1991 * Make sure the last group has enough space so that it's
1992 * guaranteed to have enough space for all metadata blocks
1993 * that it might need to hold. (We might not need to store
1994 * the inode table blocks in the last block group, but there
1995 * will be cases where this might be needed.)
1996 */
1997 if ((ext4_group_first_block_no(sb, n_group) +
1998 ext4_group_overhead_blocks(sb, n_group) + 2 +
1999 sbi->s_itb_per_group + sbi->s_cluster_ratio) >= n_blocks_count) {
2000 n_blocks_count = ext4_group_first_block_no(sb, n_group);
2001 n_group--;
2002 n_blocks_count_retry = 0;
2003 if (resize_inode) {
2004 iput(resize_inode);
2005 resize_inode = NULL;
2006 }
2007 goto retry;
2008 }
2009
1989 /* extend the last group */ 2010 /* extend the last group */
1990 if (n_group == o_group) 2011 if (n_group == o_group)
1991 add = n_blocks_count - o_blocks_count; 2012 add = n_blocks_count - o_blocks_count;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 5863fd22e90b..1145109968ef 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2145,6 +2145,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
2145 SEQ_OPTS_PRINT("max_dir_size_kb=%u", sbi->s_max_dir_size_kb); 2145 SEQ_OPTS_PRINT("max_dir_size_kb=%u", sbi->s_max_dir_size_kb);
2146 if (test_opt(sb, DATA_ERR_ABORT)) 2146 if (test_opt(sb, DATA_ERR_ABORT))
2147 SEQ_OPTS_PUTS("data_err=abort"); 2147 SEQ_OPTS_PUTS("data_err=abort");
2148 if (DUMMY_ENCRYPTION_ENABLED(sbi))
2149 SEQ_OPTS_PUTS("test_dummy_encryption");
2148 2150
2149 ext4_show_quota_options(seq, sb); 2151 ext4_show_quota_options(seq, sb);
2150 return 0; 2152 return 0;
@@ -4378,11 +4380,13 @@ no_journal:
4378 block = ext4_count_free_clusters(sb); 4380 block = ext4_count_free_clusters(sb);
4379 ext4_free_blocks_count_set(sbi->s_es, 4381 ext4_free_blocks_count_set(sbi->s_es,
4380 EXT4_C2B(sbi, block)); 4382 EXT4_C2B(sbi, block));
4383 ext4_superblock_csum_set(sb);
4381 err = percpu_counter_init(&sbi->s_freeclusters_counter, block, 4384 err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
4382 GFP_KERNEL); 4385 GFP_KERNEL);
4383 if (!err) { 4386 if (!err) {
4384 unsigned long freei = ext4_count_free_inodes(sb); 4387 unsigned long freei = ext4_count_free_inodes(sb);
4385 sbi->s_es->s_free_inodes_count = cpu_to_le32(freei); 4388 sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
4389 ext4_superblock_csum_set(sb);
4386 err = percpu_counter_init(&sbi->s_freeinodes_counter, freei, 4390 err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
4387 GFP_KERNEL); 4391 GFP_KERNEL);
4388 } 4392 }