Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 339e1a3f authored by Eric Sandeen's avatar Eric Sandeen Committed by Dave Chinner
Browse files

xfs: validate inode di_forkoff



Verify the inode di_forkoff, lifted from xfs_repair's
process_check_inode_forkoff().

Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent f5f3f959
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -415,6 +415,31 @@ xfs_dinode_verify_fork(
	return NULL;
}

static xfs_failaddr_t
xfs_dinode_verify_forkoff(
	struct xfs_dinode	*dip,
	struct xfs_mount	*mp)
{
	if (!XFS_DFORK_Q(dip))
		return NULL;

	switch (dip->di_format)  {
	case XFS_DINODE_FMT_DEV:
		if (dip->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3))
			return __this_address;
		break;
	case XFS_DINODE_FMT_LOCAL:	/* fall through ... */
	case XFS_DINODE_FMT_EXTENTS:    /* fall through ... */
	case XFS_DINODE_FMT_BTREE:
		if (dip->di_forkoff >= (XFS_LITINO(mp, dip->di_version) >> 3))
			return __this_address;
		break;
	default:
		return __this_address;
	}
	return NULL;
}

xfs_failaddr_t
xfs_dinode_verify(
	struct xfs_mount	*mp,
@@ -470,6 +495,11 @@ xfs_dinode_verify(
	if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp)
		return __this_address;

	/* check for illegal values of forkoff */
	fa = xfs_dinode_verify_forkoff(dip, mp);
	if (fa)
		return fa;

	/* Do we have appropriate data fork formats for the mode? */
	switch (mode & S_IFMT) {
	case S_IFIFO: