aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_inode_buf.c
diff options
context:
space:
mode:
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: