* [PATCH AUTOSEL 6.11 234/244] ext4: filesystems without casefold feature cannot be mounted with siphash
[not found] <20240925113641.1297102-1-sashal@kernel.org>
@ 2024-09-25 11:27 ` Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 235/244] ext4: don't set SB_RDONLY after filesystem errors Sasha Levin
` (3 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2024-09-25 11:27 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Lizhi Xu, syzbot+340581ba9dceb7e06fb3, Theodore Ts'o,
Sasha Levin, adilger.kernel, linux-ext4
From: Lizhi Xu <lizhi.xu@windriver.com>
[ Upstream commit 985b67cd86392310d9e9326de941c22fc9340eec ]
When mounting the ext4 filesystem, if the default hash version is set to
DX_HASH_SIPHASH but the casefold feature is not set, exit the mounting.
Reported-by: syzbot+340581ba9dceb7e06fb3@syzkaller.appspotmail.com
Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
Link: https://patch.msgid.link/20240605012335.44086-1-lizhi.xu@windriver.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e72145c4ae5a0..25cd0d662e31b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3582,6 +3582,13 @@ int ext4_feature_set_ok(struct super_block *sb, int readonly)
"mounted without CONFIG_UNICODE");
return 0;
}
+ if (EXT4_SB(sb)->s_es->s_def_hash_version == DX_HASH_SIPHASH &&
+ !ext4_has_feature_casefold(sb)) {
+ ext4_msg(sb, KERN_ERR,
+ "Filesystem without casefold feature cannot be "
+ "mounted with siphash");
+ return 0;
+ }
if (readonly)
return 1;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 6.11 235/244] ext4: don't set SB_RDONLY after filesystem errors
[not found] <20240925113641.1297102-1-sashal@kernel.org>
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 234/244] ext4: filesystems without casefold feature cannot be mounted with siphash Sasha Levin
@ 2024-09-25 11:27 ` Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 238/244] ext4: ext4_search_dir should return a proper error Sasha Levin
` (2 subsequent siblings)
4 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2024-09-25 11:27 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Jan Kara, Christian Brauner, Theodore Ts'o, Sasha Levin,
adilger.kernel, linux-ext4
From: Jan Kara <jack@suse.cz>
[ Upstream commit d3476f3dad4ad68ae5f6b008ea6591d1520da5d8 ]
When the filesystem is mounted with errors=remount-ro, we were setting
SB_RDONLY flag to stop all filesystem modifications. We knew this misses
proper locking (sb->s_umount) and does not go through proper filesystem
remount procedure but it has been the way this worked since early ext2
days and it was good enough for catastrophic situation damage
mitigation. Recently, syzbot has found a way (see link) to trigger
warnings in filesystem freezing because the code got confused by
SB_RDONLY changing under its hands. Since these days we set
EXT4_FLAGS_SHUTDOWN on the superblock which is enough to stop all
filesystem modifications, modifying SB_RDONLY shouldn't be needed. So
stop doing that.
Link: https://lore.kernel.org/all/000000000000b90a8e061e21d12f@google.com
Reported-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Link: https://patch.msgid.link/20240805201241.27286-1-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 25cd0d662e31b..e8e32cf3e2228 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -735,11 +735,12 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
/*
- * Make sure updated value of ->s_mount_flags will be visible before
- * ->s_flags update
+ * EXT4_FLAGS_SHUTDOWN was set which stops all filesystem
+ * modifications. We don't set SB_RDONLY because that requires
+ * sb->s_umount semaphore and setting it without proper remount
+ * procedure is confusing code such as freeze_super() leading to
+ * deadlocks and other problems.
*/
- smp_wmb();
- sb->s_flags |= SB_RDONLY;
}
static void update_super_work(struct work_struct *work)
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 6.11 238/244] ext4: ext4_search_dir should return a proper error
[not found] <20240925113641.1297102-1-sashal@kernel.org>
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 234/244] ext4: filesystems without casefold feature cannot be mounted with siphash Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 235/244] ext4: don't set SB_RDONLY after filesystem errors Sasha Levin
@ 2024-09-25 11:27 ` Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 239/244] ext4: avoid use-after-free in ext4_ext_show_leaf() Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 240/244] ext4: fix i_data_sem unlock order in ext4_ind_migrate() Sasha Levin
4 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2024-09-25 11:27 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Thadeu Lima de Souza Cascardo, Theodore Ts'o, Sasha Levin,
adilger.kernel, linux-ext4
From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
[ Upstream commit cd69f8f9de280e331c9e6ff689ced0a688a9ce8f ]
ext4_search_dir currently returns -1 in case of a failure, while it returns
0 when the name is not found. In such failure cases, it should return an
error code instead.
This becomes even more important when ext4_find_inline_entry returns an
error code as well in the next commit.
-EFSCORRUPTED seems appropriate as such error code as these failures would
be caused by unexpected record lengths and is in line with other instances
of ext4_check_dir_entry failures.
In the case of ext4_dx_find_entry, the current use of ERR_BAD_DX_DIR was
left as is to reduce the risk of regressions.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Link: https://patch.msgid.link/20240821152324.3621860-2-cascardo@igalia.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/namei.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 6a95713f9193b..8af437ac30511 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1482,7 +1482,7 @@ static bool ext4_match(struct inode *parent,
}
/*
- * Returns 0 if not found, -1 on failure, and 1 on success
+ * Returns 0 if not found, -EFSCORRUPTED on failure, and 1 on success
*/
int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
struct inode *dir, struct ext4_filename *fname,
@@ -1503,7 +1503,7 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
* a full check */
if (ext4_check_dir_entry(dir, NULL, de, bh, search_buf,
buf_size, offset))
- return -1;
+ return -EFSCORRUPTED;
*res_dir = de;
return 1;
}
@@ -1511,7 +1511,7 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
de_len = ext4_rec_len_from_disk(de->rec_len,
dir->i_sb->s_blocksize);
if (de_len <= 0)
- return -1;
+ return -EFSCORRUPTED;
offset += de_len;
de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
}
@@ -1663,8 +1663,10 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir,
goto cleanup_and_exit;
} else {
brelse(bh);
- if (i < 0)
+ if (i < 0) {
+ ret = ERR_PTR(i);
goto cleanup_and_exit;
+ }
}
next:
if (++block >= nblocks)
@@ -1758,7 +1760,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
if (retval == 1)
goto success;
brelse(bh);
- if (retval == -1) {
+ if (retval < 0) {
bh = ERR_PTR(ERR_BAD_DX_DIR);
goto errout;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 6.11 239/244] ext4: avoid use-after-free in ext4_ext_show_leaf()
[not found] <20240925113641.1297102-1-sashal@kernel.org>
` (2 preceding siblings ...)
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 238/244] ext4: ext4_search_dir should return a proper error Sasha Levin
@ 2024-09-25 11:27 ` Sasha Levin
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 240/244] ext4: fix i_data_sem unlock order in ext4_ind_migrate() Sasha Levin
4 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2024-09-25 11:27 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Baokun Li, Jan Kara, Ojaswin Mujoo, Theodore Ts'o,
Sasha Levin, adilger.kernel, linux-ext4
From: Baokun Li <libaokun1@huawei.com>
[ Upstream commit 4e2524ba2ca5f54bdbb9e5153bea00421ef653f5 ]
In ext4_find_extent(), path may be freed by error or be reallocated, so
using a previously saved *ppath may have been freed and thus may trigger
use-after-free, as follows:
ext4_split_extent
path = *ppath;
ext4_split_extent_at(ppath)
path = ext4_find_extent(ppath)
ext4_split_extent_at(ppath)
// ext4_find_extent fails to free path
// but zeroout succeeds
ext4_ext_show_leaf(inode, path)
eh = path[depth].p_hdr
// path use-after-free !!!
Similar to ext4_split_extent_at(), we use *ppath directly as an input to
ext4_ext_show_leaf(). Fix a spelling error by the way.
Same problem in ext4_ext_handle_unwritten_extents(). Since 'path' is only
used in ext4_ext_show_leaf(), remove 'path' and use *ppath directly.
This issue is triggered only when EXT_DEBUG is defined and therefore does
not affect functionality.
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Tested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://patch.msgid.link/20240822023545.1994557-5-libaokun@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/extents.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e067f2dd0335c..7954430f886d8 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3287,7 +3287,7 @@ static int ext4_split_extent_at(handle_t *handle,
}
/*
- * ext4_split_extents() splits an extent and mark extent which is covered
+ * ext4_split_extent() splits an extent and mark extent which is covered
* by @map as split_flags indicates
*
* It may result in splitting the extent into multiple extents (up to three)
@@ -3363,7 +3363,7 @@ static int ext4_split_extent(handle_t *handle,
goto out;
}
- ext4_ext_show_leaf(inode, path);
+ ext4_ext_show_leaf(inode, *ppath);
out:
return err ? err : allocated;
}
@@ -3828,14 +3828,13 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
struct ext4_ext_path **ppath, int flags,
unsigned int allocated, ext4_fsblk_t newblock)
{
- struct ext4_ext_path __maybe_unused *path = *ppath;
int ret = 0;
int err = 0;
ext_debug(inode, "logical block %llu, max_blocks %u, flags 0x%x, allocated %u\n",
(unsigned long long)map->m_lblk, map->m_len, flags,
allocated);
- ext4_ext_show_leaf(inode, path);
+ ext4_ext_show_leaf(inode, *ppath);
/*
* When writing into unwritten space, we should not fail to
@@ -3932,7 +3931,7 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
if (allocated > map->m_len)
allocated = map->m_len;
map->m_len = allocated;
- ext4_ext_show_leaf(inode, path);
+ ext4_ext_show_leaf(inode, *ppath);
out2:
return err ? err : allocated;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 6.11 240/244] ext4: fix i_data_sem unlock order in ext4_ind_migrate()
[not found] <20240925113641.1297102-1-sashal@kernel.org>
` (3 preceding siblings ...)
2024-09-25 11:27 ` [PATCH AUTOSEL 6.11 239/244] ext4: avoid use-after-free in ext4_ext_show_leaf() Sasha Levin
@ 2024-09-25 11:27 ` Sasha Levin
4 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2024-09-25 11:27 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Artem Sadovnikov, Ritesh Harjani, Mikhail Ukhin,
Theodore Ts'o, Sasha Levin, adilger.kernel, linux-ext4
From: Artem Sadovnikov <ancowi69@gmail.com>
[ Upstream commit cc749e61c011c255d81b192a822db650c68b313f ]
Fuzzing reports a possible deadlock in jbd2_log_wait_commit.
This issue is triggered when an EXT4_IOC_MIGRATE ioctl is set to require
synchronous updates because the file descriptor is opened with O_SYNC.
This can lead to the jbd2_journal_stop() function calling
jbd2_might_wait_for_commit(), potentially causing a deadlock if the
EXT4_IOC_MIGRATE call races with a write(2) system call.
This problem only arises when CONFIG_PROVE_LOCKING is enabled. In this
case, the jbd2_might_wait_for_commit macro locks jbd2_handle in the
jbd2_journal_stop function while i_data_sem is locked. This triggers
lockdep because the jbd2_journal_start function might also lock the same
jbd2_handle simultaneously.
Found by Linux Verification Center (linuxtesting.org) with syzkaller.
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Co-developed-by: Mikhail Ukhin <mish.uxin2012@yandex.ru>
Signed-off-by: Mikhail Ukhin <mish.uxin2012@yandex.ru>
Signed-off-by: Artem Sadovnikov <ancowi69@gmail.com>
Rule: add
Link: https://lore.kernel.org/stable/20240404095000.5872-1-mish.uxin2012%40yandex.ru
Link: https://patch.msgid.link/20240829152210.2754-1-ancowi69@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/migrate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index d98ac2af8199f..a5e1492bbaaa5 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -663,8 +663,8 @@ int ext4_ind_migrate(struct inode *inode)
if (unlikely(ret2 && !ret))
ret = ret2;
errout:
- ext4_journal_stop(handle);
up_write(&EXT4_I(inode)->i_data_sem);
+ ext4_journal_stop(handle);
out_unlock:
ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread