From: Darrick J. Wong Date: Wed, 23 May 2018 21:30:48 +0000 (-0500) Subject: xfs_repair: validate some of the log space information X-Git-Tag: v4.17.0-rc1~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb9cee60389948e2b91a5177a9a491dbf44be815;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: validate some of the log space information Validate the log space information in a similar manner to the kernel so that repair will stumble over (and fix) broken log info that prevents mounting. Fixes logsunit fuzz-and-fix failures in xfs/350. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson Signed-off-by: Eric Sandeen --- diff --git a/repair/globals.h b/repair/globals.h index e777ba275..164619b0e 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -51,7 +51,8 @@ #define XR_BAD_SVN 19 /* bad shared version number */ #define XR_BAD_CRC 20 /* Bad CRC */ #define XR_BAD_DIR_SIZE_DATA 21 /* Bad directory geometry */ -#define XR_BAD_ERR_CODE 22 /* Bad error code */ +#define XR_BAD_LOG_GEOMETRY 22 /* Bad log geometry */ +#define XR_BAD_ERR_CODE 23 /* Bad error code */ /* XFS filesystem (il)legal values */ diff --git a/repair/sb.c b/repair/sb.c index 3dc6538bb..ef44e39c7 100644 --- a/repair/sb.c +++ b/repair/sb.c @@ -298,6 +298,30 @@ sb_validate_ino_align(struct xfs_sb *sb) return false; } +/* + * Validate the given log space. Derived from xfs_log_mount, though we + * can't validate the minimum log size until later. We only do this + * validation on V5 filesystems because the kernel doesn't reject malformed + * log geometry on older revision filesystems. + * + * Returns false if the log is garbage. + */ +static bool +verify_sb_loginfo( + struct xfs_sb *sb) +{ + if (xfs_sb_version_hascrc(sb) && + (sb->sb_logblocks == 0 || + sb->sb_logblocks > XFS_MAX_LOG_BLOCKS || + (sb->sb_logblocks << sb->sb_blocklog) > XFS_MAX_LOG_BYTES)) + return false; + + if (sb->sb_logsunit > 1 && sb->sb_logsunit % sb->sb_blocksize) + return false; + + return true; +} + /* * verify a superblock -- does not verify root inode # * can only check that geometry info is internally @@ -412,6 +436,9 @@ verify_sb(char *sb_buf, xfs_sb_t *sb, int is_primary_sb) (sb->sb_blocklog - sb->sb_inodelog != sb->sb_inopblog)) return XR_BAD_INO_SIZE_DATA; + if (!verify_sb_loginfo(sb)) + return XR_BAD_LOG_GEOMETRY; + if (xfs_sb_version_hassector(sb)) { /* check to make sure log sector is legal 2^N, 9 <= N <= 15 */ diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index ff6a73842..b7c2d2671 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -155,6 +155,8 @@ err_string(int err_code) _("bad CRC in superblock"); err_message[XR_BAD_DIR_SIZE_DATA] = _("inconsistent directory geometry information"); + err_message[XR_BAD_LOG_GEOMETRY] = + _("inconsistent log geometry information"); done = 1; }