xfs: explicitly pass buffer size to xfs_corruption_error
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 4 Jun 2018 17:23:54 +0000 (10:23 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Tue, 5 Jun 2018 01:25:05 +0000 (18:25 -0700)
Explicitly pass the buffer length to xfs_corruption_error() instead of
assuming XFS_CORRUPTION_DUMP_LEN so that we avoid dumping off the end
of the buffer.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_da_btree.c
fs/xfs/libxfs/xfs_dir2_data.c
fs/xfs/libxfs/xfs_dir2_leaf.c
fs/xfs/libxfs/xfs_dir2_node.c
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h
fs/xfs/xfs_log_recover.c

index 4f83d79..6b589e4 100644 (file)
@@ -1932,7 +1932,8 @@ xfs_btree_lookup(
                                if (level != 0 || cur->bc_nlevels != 1) {
                                        XFS_CORRUPTION_ERROR(__func__,
                                                        XFS_ERRLEVEL_LOW,
-                                                       cur->bc_mp, block);
+                                                       cur->bc_mp, block,
+                                                       sizeof(*block));
                                        return -EFSCORRUPTED;
                                }
 
index 39c1013..1427887 100644 (file)
@@ -306,7 +306,7 @@ xfs_da3_node_read(
                        break;
                default:
                        XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                       tp->t_mountp, info);
+                                       tp->t_mountp, info, sizeof(*info));
                        xfs_trans_brelse(tp, *bpp);
                        *bpp = NULL;
                        return -EFSCORRUPTED;
index 2c16bb4..c672846 100644 (file)
@@ -251,7 +251,8 @@ xfs_dir3_data_check(
        if (!fa)
                return;
        xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, dp->i_mount,
-                       bp->b_addr, __FILE__, __LINE__, fa);
+                       bp->b_addr, BBTOB(bp->b_length), __FILE__, __LINE__,
+                       fa);
        ASSERT(0);
 }
 #endif
@@ -1157,7 +1158,7 @@ xfs_dir2_data_use_free(
        return 0;
 corrupt:
        xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount,
-                       hdr, __FILE__, __LINE__, fa);
+                       hdr, sizeof(*hdr), __FILE__, __LINE__, fa);
        return -EFSCORRUPTED;
 }
 
index 9367f2a..77240f4 100644 (file)
@@ -81,7 +81,8 @@ xfs_dir3_leaf_check(
        if (!fa)
                return;
        xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, dp->i_mount,
-                       bp->b_addr, __FILE__, __LINE__, fa);
+                       bp->b_addr, BBTOB(bp->b_length), __FILE__, __LINE__,
+                       fa);
        ASSERT(0);
 }
 #else
index 9df096c..a5e7d9b 100644 (file)
@@ -84,7 +84,8 @@ xfs_dir3_leaf_check(
        if (!fa)
                return;
        xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, dp->i_mount,
-                       bp->b_addr, __FILE__, __LINE__, fa);
+                       bp->b_addr, BBTOB(bp->b_length), __FILE__, __LINE__,
+                       fa);
        ASSERT(0);
 }
 #else
index 3e59a34..276465e 100644 (file)
@@ -139,7 +139,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
                    ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) {
                        XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
                                             XFS_ERRLEVEL_LOW,
-                                            context->dp->i_mount, sfe);
+                                            context->dp->i_mount, sfe,
+                                            sizeof(*sfe));
                        kmem_free(sbuf);
                        return -EFSCORRUPTED;
                }
@@ -241,7 +242,7 @@ xfs_attr_node_list_lookup(
                if (magic != XFS_DA_NODE_MAGIC &&
                    magic != XFS_DA3_NODE_MAGIC) {
                        XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
-                                       node);
+                                       node, sizeof(*node));
                        goto out_corruptbuf;
                }
 
index 7975634..fedb273 100644 (file)
@@ -334,13 +334,14 @@ xfs_corruption_error(
        const char              *tag,
        int                     level,
        struct xfs_mount        *mp,
-       void                    *p,
+       void                    *buf,
+       size_t                  bufsize,
        const char              *filename,
        int                     linenum,
        xfs_failaddr_t          failaddr)
 {
        if (level <= xfs_error_level)
-               xfs_hex_dump(p, XFS_CORRUPTION_DUMP_LEN);
+               xfs_hex_dump(buf, bufsize);
        xfs_error_report(tag, level, mp, filename, linenum, failaddr);
        xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
 }
index ce39134..f8c3667 100644 (file)
@@ -24,8 +24,9 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp,
                        const char *filename, int linenum,
                        xfs_failaddr_t failaddr);
 extern void xfs_corruption_error(const char *tag, int level,
-                       struct xfs_mount *mp, void *p, const char *filename,
-                       int linenum, xfs_failaddr_t failaddr);
+                       struct xfs_mount *mp, void *buf, size_t bufsize,
+                       const char *filename, int linenum,
+                       xfs_failaddr_t failaddr);
 extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error,
                        const char *name, void *buf, size_t bufsz,
                        xfs_failaddr_t failaddr);
@@ -37,8 +38,8 @@ extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error,
 
 #define        XFS_ERROR_REPORT(e, lvl, mp)    \
        xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
-#define        XFS_CORRUPTION_ERROR(e, lvl, mp, mem)   \
-       xfs_corruption_error(e, lvl, mp, mem, \
+#define        XFS_CORRUPTION_ERROR(e, lvl, mp, buf, bufsize)  \
+       xfs_corruption_error(e, lvl, mp, buf, bufsize, \
                             __FILE__, __LINE__, __return_address)
 
 #define XFS_ERRLEVEL_OFF       0
index 06a09cb..750124b 100644 (file)
@@ -3115,7 +3115,8 @@ xlog_recover_inode_pass2(
                if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
                    (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
                        XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
-                                        XFS_ERRLEVEL_LOW, mp, ldip);
+                                        XFS_ERRLEVEL_LOW, mp, ldip,
+                                        sizeof(*ldip));
                        xfs_alert(mp,
                "%s: Bad regular inode log record, rec ptr "PTR_FMT", "
                "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld",
@@ -3128,7 +3129,8 @@ xlog_recover_inode_pass2(
                    (ldip->di_format != XFS_DINODE_FMT_BTREE) &&
                    (ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
                        XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
-                                            XFS_ERRLEVEL_LOW, mp, ldip);
+                                            XFS_ERRLEVEL_LOW, mp, ldip,
+                                            sizeof(*ldip));
                        xfs_alert(mp,
                "%s: Bad dir inode log record, rec ptr "PTR_FMT", "
                "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld",
@@ -3139,7 +3141,8 @@ xlog_recover_inode_pass2(
        }
        if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
                XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
-                                    XFS_ERRLEVEL_LOW, mp, ldip);
+                                    XFS_ERRLEVEL_LOW, mp, ldip,
+                                    sizeof(*ldip));
                xfs_alert(mp,
        "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
        "dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld",
@@ -3151,7 +3154,8 @@ xlog_recover_inode_pass2(
        }
        if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
                XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
-                                    XFS_ERRLEVEL_LOW, mp, ldip);
+                                    XFS_ERRLEVEL_LOW, mp, ldip,
+                                    sizeof(*ldip));
                xfs_alert(mp,
        "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
        "dino bp "PTR_FMT", ino %Ld, forkoff 0x%x", __func__,
@@ -3162,7 +3166,8 @@ xlog_recover_inode_pass2(
        isize = xfs_log_dinode_size(ldip->di_version);
        if (unlikely(item->ri_buf[1].i_len > isize)) {
                XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
-                                    XFS_ERRLEVEL_LOW, mp, ldip);
+                                    XFS_ERRLEVEL_LOW, mp, ldip,
+                                    sizeof(*ldip));
                xfs_alert(mp,
                        "%s: Bad inode log record length %d, rec ptr "PTR_FMT,
                        __func__, item->ri_buf[1].i_len, item);