浏览代码

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>
Eric Sandeen 6 年之前
父节点
当前提交
339e1a3fcd
共有 1 个文件被更改,包括 30 次插入0 次删除
  1. 30 0
      fs/xfs/libxfs/xfs_inode_buf.c

+ 30 - 0
fs/xfs/libxfs/xfs_inode_buf.c

@@ -415,6 +415,31 @@ xfs_dinode_verify_fork(
 	return NULL;
 	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_failaddr_t
 xfs_dinode_verify(
 xfs_dinode_verify(
 	struct xfs_mount	*mp,
 	struct xfs_mount	*mp,
@@ -470,6 +495,11 @@ xfs_dinode_verify(
 	if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp)
 	if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp)
 		return __this_address;
 		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? */
 	/* Do we have appropriate data fork formats for the mode? */
 	switch (mode & S_IFMT) {
 	switch (mode & S_IFMT) {
 	case S_IFIFO:
 	case S_IFIFO: