diff options
author | Eric Sandeen <sandeen@redhat.com> | 2018-09-28 23:50:13 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2018-09-28 23:50:13 -0400 |
commit | 339e1a3fcdd1990e5ec115325ccb4c6f4cc5ee16 (patch) | |
tree | 4c79b25ae0de976e3e6ff5398fd649b982d393ec /fs/xfs/libxfs | |
parent | f5f3f959b70b272dfe2d05758e43ae52f5ff7748 (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')
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 30 |
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 | ||
418 | static xfs_failaddr_t | ||
419 | xfs_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 | |||
418 | xfs_failaddr_t | 443 | xfs_failaddr_t |
419 | xfs_dinode_verify( | 444 | xfs_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: |