aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_inode_buf.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2018-09-28 23:50:13 -0400
committerDave Chinner <david@fromorbit.com>2018-09-28 23:50:13 -0400
commit339e1a3fcdd1990e5ec115325ccb4c6f4cc5ee16 (patch)
tree4c79b25ae0de976e3e6ff5398fd649b982d393ec /fs/xfs/libxfs/xfs_inode_buf.c
parentf5f3f959b70b272dfe2d05758e43ae52f5ff7748 (diff)
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>
Diffstat (limited to 'fs/xfs/libxfs/xfs_inode_buf.c')
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 30d1d60f1d46..09d9c8cfa4a0 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -415,6 +415,31 @@ xfs_dinode_verify_fork(
415 return NULL; 415 return NULL;
416} 416}
417 417
418static xfs_failaddr_t
419xfs_dinode_verify_forkoff(
420 struct xfs_dinode *dip,
421 struct xfs_mount *mp)
422{
423 if (!XFS_DFORK_Q(dip))
424 return NULL;
425
426 switch (dip->di_format) {
427 case XFS_DINODE_FMT_DEV:
428 if (dip->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3))
429 return __this_address;
430 break;
431 case XFS_DINODE_FMT_LOCAL: /* fall through ... */
432 case XFS_DINODE_FMT_EXTENTS: /* fall through ... */
433 case XFS_DINODE_FMT_BTREE:
434 if (dip->di_forkoff >= (XFS_LITINO(mp, dip->di_version) >> 3))
435 return __this_address;
436 break;
437 default:
438 return __this_address;
439 }
440 return NULL;
441}
442
418xfs_failaddr_t 443xfs_failaddr_t
419xfs_dinode_verify( 444xfs_dinode_verify(
420 struct xfs_mount *mp, 445 struct xfs_mount *mp,
@@ -470,6 +495,11 @@ xfs_dinode_verify(
470 if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp) 495 if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp)
471 return __this_address; 496 return __this_address;
472 497
498 /* check for illegal values of forkoff */
499 fa = xfs_dinode_verify_forkoff(dip, mp);
500 if (fa)
501 return fa;
502
473 /* Do we have appropriate data fork formats for the mode? */ 503 /* Do we have appropriate data fork formats for the mode? */
474 switch (mode & S_IFMT) { 504 switch (mode & S_IFMT) {
475 case S_IFIFO: 505 case S_IFIFO: