Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Iliopoulos <ailiopoulos@suse.com>2019-05-18 01:27:45 +0200
committerAnthony Iliopoulos <ailiopoulos@suse.com>2019-05-18 01:27:45 +0200
commit2fc02cbeab9e6df423ed9f51e8276887a11fc0d7 (patch)
tree9efdfb65e7c600afa9e4c1ec5cd5429baa374af7
parent7c870d331fec250002b15094ae5b96a6a0a04472 (diff)
xfs: create inode pointer verifiers (bsc#1114427).
-rw-r--r--patches.fixes/xfs-create-inode-pointer-verifiers.patch212
-rw-r--r--series.conf1
2 files changed, 213 insertions, 0 deletions
diff --git a/patches.fixes/xfs-create-inode-pointer-verifiers.patch b/patches.fixes/xfs-create-inode-pointer-verifiers.patch
new file mode 100644
index 0000000000..63a7eb4284
--- /dev/null
+++ b/patches.fixes/xfs-create-inode-pointer-verifiers.patch
@@ -0,0 +1,212 @@
+From 91fb9afc0847926ef6ea7695b8125c8fbe7974d6 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Tue, 17 Oct 2017 21:37:34 -0700
+Subject: [PATCH] xfs: create inode pointer verifiers
+Git-commit: 91fb9afc0847926ef6ea7695b8125c8fbe7974d6
+Patch-mainline: v4.15-rc1
+References: bsc#1114427
+
+Create some helper functions to check that inode pointers point to
+somewhere within the filesystem and not at the static AG metadata.
+Move xfs_internal_inum and create a directory inode check function.
+We will use these functions in scrub and elsewhere.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/libxfs/xfs_dir2.c | 19 ++--------
+ fs/xfs/libxfs/xfs_ialloc.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++
+ fs/xfs/libxfs/xfs_ialloc.h | 7 ++++
+ fs/xfs/xfs_itable.c | 10 ------
+ fs/xfs/xfs_itable.h | 2 --
+ 5 files changed, 100 insertions(+), 28 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
+index ccf9783fd3f0..ee5e9160eb01 100644
+--- a/fs/xfs/libxfs/xfs_dir2.c
++++ b/fs/xfs/libxfs/xfs_dir2.c
+@@ -30,6 +30,7 @@
+ #include "xfs_bmap.h"
+ #include "xfs_dir2.h"
+ #include "xfs_dir2_priv.h"
++#include "xfs_ialloc.h"
+ #include "xfs_error.h"
+ #include "xfs_trace.h"
+
+@@ -202,22 +203,8 @@ xfs_dir_ino_validate(
+ xfs_mount_t *mp,
+ xfs_ino_t ino)
+ {
+- xfs_agblock_t agblkno;
+- xfs_agino_t agino;
+- xfs_agnumber_t agno;
+- int ino_ok;
+- int ioff;
+-
+- agno = XFS_INO_TO_AGNO(mp, ino);
+- agblkno = XFS_INO_TO_AGBNO(mp, ino);
+- ioff = XFS_INO_TO_OFFSET(mp, ino);
+- agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
+- ino_ok =
+- agno < mp->m_sb.sb_agcount &&
+- agblkno < mp->m_sb.sb_agblocks &&
+- agblkno != 0 &&
+- ioff < (1 << mp->m_sb.sb_inopblog) &&
+- XFS_AGINO_TO_INO(mp, agno, agino) == ino;
++ bool ino_ok = xfs_verify_dir_ino(mp, ino);
++
+ if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE))) {
+ xfs_warn(mp, "Invalid inode number 0x%Lx",
+ (unsigned long long) ino);
+diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
+index dfd643909f85..e11f8af8a725 100644
+--- a/fs/xfs/libxfs/xfs_ialloc.c
++++ b/fs/xfs/libxfs/xfs_ialloc.c
+@@ -2664,3 +2664,93 @@ xfs_ialloc_pagi_init(
+ xfs_trans_brelse(tp, bp);
+ return 0;
+ }
++
++/* Calculate the first and last possible inode number in an AG. */
++void
++xfs_ialloc_agino_range(
++ struct xfs_mount *mp,
++ xfs_agnumber_t agno,
++ xfs_agino_t *first,
++ xfs_agino_t *last)
++{
++ xfs_agblock_t bno;
++ xfs_agblock_t eoag;
++
++ eoag = xfs_ag_block_count(mp, agno);
++
++ /*
++ * Calculate the first inode, which will be in the first
++ * cluster-aligned block after the AGFL.
++ */
++ bno = round_up(XFS_AGFL_BLOCK(mp) + 1,
++ xfs_ialloc_cluster_alignment(mp));
++ *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0);
++
++ /*
++ * Calculate the last inode, which will be at the end of the
++ * last (aligned) cluster that can be allocated in the AG.
++ */
++ bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp));
++ *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1;
++}
++
++/*
++ * Verify that an AG inode number pointer neither points outside the AG
++ * nor points at static metadata.
++ */
++bool
++xfs_verify_agino(
++ struct xfs_mount *mp,
++ xfs_agnumber_t agno,
++ xfs_agino_t agino)
++{
++ xfs_agino_t first;
++ xfs_agino_t last;
++
++ xfs_ialloc_agino_range(mp, agno, &first, &last);
++ return agino >= first && agino <= last;
++}
++
++/*
++ * Verify that an FS inode number pointer neither points outside the
++ * filesystem nor points at static AG metadata.
++ */
++bool
++xfs_verify_ino(
++ struct xfs_mount *mp,
++ xfs_ino_t ino)
++{
++ xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino);
++ xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino);
++
++ if (agno >= mp->m_sb.sb_agcount)
++ return false;
++ if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
++ return false;
++ return xfs_verify_agino(mp, agno, agino);
++}
++
++/* Is this an internal inode number? */
++bool
++xfs_internal_inum(
++ struct xfs_mount *mp,
++ xfs_ino_t ino)
++{
++ return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
++ (xfs_sb_version_hasquota(&mp->m_sb) &&
++ xfs_is_quota_inode(&mp->m_sb, ino));
++}
++
++/*
++ * Verify that a directory entry's inode number doesn't point at an internal
++ * inode, empty space, or static AG metadata.
++ */
++bool
++xfs_verify_dir_ino(
++ struct xfs_mount *mp,
++ xfs_ino_t ino)
++{
++ if (xfs_internal_inum(mp, ino))
++ return false;
++ return xfs_verify_ino(mp, ino);
++}
+diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h
+index b32cfb5aeb5b..d2bdcd5e7312 100644
+--- a/fs/xfs/libxfs/xfs_ialloc.h
++++ b/fs/xfs/libxfs/xfs_ialloc.h
+@@ -173,5 +173,12 @@ void xfs_inobt_btrec_to_irec(struct xfs_mount *mp, union xfs_btree_rec *rec,
+ struct xfs_inobt_rec_incore *irec);
+
+ int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
++void xfs_ialloc_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
++ xfs_agino_t *first, xfs_agino_t *last);
++bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno,
++ xfs_agino_t agino);
++bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino);
++bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
++bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
+
+ #endif /* __XFS_IALLOC_H__ */
+diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
+index c393a2f6d8c3..0172d0b72c95 100644
+--- a/fs/xfs/xfs_itable.c
++++ b/fs/xfs/xfs_itable.c
+@@ -31,16 +31,6 @@
+ #include "xfs_trace.h"
+ #include "xfs_icache.h"
+
+-int
+-xfs_internal_inum(
+- xfs_mount_t *mp,
+- xfs_ino_t ino)
+-{
+- return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
+- (xfs_sb_version_hasquota(&mp->m_sb) &&
+- xfs_is_quota_inode(&mp->m_sb, ino)));
+-}
+-
+ /*
+ * Return stat information for one inode.
+ * Return 0 if ok, else errno.
+diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
+index 17e86e0541af..6ea8b3912fa4 100644
+--- a/fs/xfs/xfs_itable.h
++++ b/fs/xfs/xfs_itable.h
+@@ -96,6 +96,4 @@ xfs_inumbers(
+ void __user *buffer, /* buffer with inode info */
+ inumbers_fmt_pf formatter);
+
+-int xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
+-
+ #endif /* __XFS_ITABLE_H__ */
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index a291d158a5..298def45fc 100644
--- a/series.conf
+++ b/series.conf
@@ -8246,6 +8246,7 @@
patches.fixes/xfs-create-block-pointer-check-functions.patch
patches.fixes/xfs-refactor-btree-pointer-checks.patch
patches.fixes/xfs-refactor-btree-block-header-checking-functions.patch
+ patches.fixes/xfs-create-inode-pointer-verifiers.patch
patches.fixes/0029-xfs-add-a-xfs_bmap_fork_to_state-helper.patch
patches.fixes/0030-xfs-make-better-use-of-the-state-variable-in-xfs_bma.patch
patches.fixes/0031-xfs-remove-post-bmap-tracing-in-xfs_bmap_local_to_ex.patch