forked from Minki/linux
xfs: validate inode di_forkoff
Verify the inode di_forkoff, lifted from xfs_repair's process_check_inode_forkoff(). Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
f5f3f959b7
commit
339e1a3fcd
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user