mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 06:33:34 +00:00
xfs: fully initialize xfs_da_args in xchk_directory_blocks
While running the online fsck test suite, I noticed the following assertion in the kernel log (edited for brevity): XFS: Assertion failed: 0, file: fs/xfs/xfs_health.c, line: 571 ------------[ cut here ]------------ WARNING: CPU: 3 PID: 11667 at fs/xfs/xfs_message.c:104 assfail+0x46/0x4a [xfs] CPU: 3 PID: 11667 Comm: xfs_scrub Tainted: G W 5.19.0-rc7-xfsx #rc7 6e6475eb29fd9dda3181f81b7ca7ff961d277a40 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 RIP: 0010:assfail+0x46/0x4a [xfs] Call Trace: <TASK> xfs_dir2_isblock+0xcc/0xe0 xchk_directory_blocks+0xc7/0x420 xchk_directory+0x53/0xb0 xfs_scrub_metadata+0x2b6/0x6b0 xfs_scrubv_metadata+0x35e/0x4d0 xfs_ioc_scrubv_metadata+0x111/0x160 xfs_file_ioctl+0x4ec/0xef0 __x64_sys_ioctl+0x82/0xa0 do_syscall_64+0x2b/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 This assertion triggers in xfs_dirattr_mark_sick when the caller passes in a whichfork value that is neither of XFS_{DATA,ATTR}_FORK. The cause of this is that xchk_directory_blocks only partially initializes the xfs_da_args structure that is passed to xfs_dir2_isblock. If the data fork is not correct, the XFS_IS_CORRUPT clause will trigger. My development branch reports this failure to the health monitoring subsystem, which accesses the uninitialized args->whichfork field, leading the the assertion tripping. We really shouldn't be passing random stack contents around, so the solution here is to force the compiler to zero-initialize the struct. Found by fuzzing u3.bmx[0].blockcount = middlebit on xfs/1554. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
f0c4d9fc9c
commit
9a48b4a6fd
@ -666,7 +666,12 @@ xchk_directory_blocks(
|
||||
struct xfs_scrub *sc)
|
||||
{
|
||||
struct xfs_bmbt_irec got;
|
||||
struct xfs_da_args args;
|
||||
struct xfs_da_args args = {
|
||||
.dp = sc ->ip,
|
||||
.whichfork = XFS_DATA_FORK,
|
||||
.geo = sc->mp->m_dir_geo,
|
||||
.trans = sc->tp,
|
||||
};
|
||||
struct xfs_ifork *ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK);
|
||||
struct xfs_mount *mp = sc->mp;
|
||||
xfs_fileoff_t leaf_lblk;
|
||||
@ -689,9 +694,6 @@ xchk_directory_blocks(
|
||||
free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET);
|
||||
|
||||
/* Is this a block dir? */
|
||||
args.dp = sc->ip;
|
||||
args.geo = mp->m_dir_geo;
|
||||
args.trans = sc->tp;
|
||||
error = xfs_dir2_isblock(&args, &is_block);
|
||||
if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error))
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user