summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_extfree_item.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-10-25 15:14:06 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-10-31 08:58:20 -0700
commit921ed96b4f4e3bd19da7f775f39234226e6647e7 (patch)
treec5264bc8542208c33e2ac78ca8918742620021b4 /fs/xfs/xfs_extfree_item.c
parent3c5aaaced99912c9fb3352fc5af5b104df67d4aa (diff)
downloadlwn-921ed96b4f4e3bd19da7f775f39234226e6647e7.tar.gz
lwn-921ed96b4f4e3bd19da7f775f39234226e6647e7.zip
xfs: actually abort log recovery on corrupt intent-done log items
If log recovery picks up intent-done log items that are not of the correct size it needs to abort recovery and fail the mount. Debug assertions are not good enough. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_extfree_item.c')
-rw-r--r--fs/xfs/xfs_extfree_item.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index f7e52db8da66..18c224351343 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -751,12 +751,24 @@ xlog_recover_efd_commit_pass2(
xfs_lsn_t lsn)
{
struct xfs_efd_log_format *efd_formatp;
+ int buflen = item->ri_buf[0].i_len;
efd_formatp = item->ri_buf[0].i_addr;
- ASSERT(item->ri_buf[0].i_len == xfs_efd_log_format32_sizeof(
- efd_formatp->efd_nextents) ||
- item->ri_buf[0].i_len == xfs_efd_log_format64_sizeof(
- efd_formatp->efd_nextents));
+
+ if (buflen < sizeof(struct xfs_efd_log_format)) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
+ efd_formatp, buflen);
+ return -EFSCORRUPTED;
+ }
+
+ if (item->ri_buf[0].i_len != xfs_efd_log_format32_sizeof(
+ efd_formatp->efd_nextents) &&
+ item->ri_buf[0].i_len != xfs_efd_log_format64_sizeof(
+ efd_formatp->efd_nextents)) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
+ efd_formatp, buflen);
+ return -EFSCORRUPTED;
+ }
xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
return 0;