aboutsummaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_inode_buf.c
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2018-10-11 23:07:30 +0200
committerWolfram Sang <wsa@the-dreams.de>2018-10-11 23:07:30 +0200
commit90fb814b6c025da45f71db1703cffe3fe87f575c (patch)
tree5fd739d407654df6f9d6e82900a45e027dd8b9f0 /fs/xfs/libxfs/xfs_inode_buf.c
parentb30f2f65568f840e5ca522d98ba2ad73b8f59cde (diff)
parent0238df646e6224016a45505d2c111a24669ebe21 (diff)
Merge tag 'v4.19-rc7' into i2c/for-4.20
This is the 4.19-rc7 release
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(
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: