diff --git a/0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch b/0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch new file mode 100644 index 0000000000000000000000000000000000000000..ec81ca69d662c2824d05880c0816519515f143e8 --- /dev/null +++ b/0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch @@ -0,0 +1,110 @@ +From ba1a8f18fcb80e3b11a318ad8adf75cd0a750000 Mon Sep 17 00:00:00 2001 +From: Zheng Bin +Date: Wed, 29 Apr 2020 14:10:49 -0400 +Subject: [PATCH 01/16] xfs: add agf freeblocks verify in xfs_agf_verify + +Source kernel commit: d0c7feaf87678371c2c09b3709400be416b2dc62 + +We recently used fuzz(hydra) to test XFS and automatically generate +tmp.img(XFS v5 format, but some metadata is wrong) + +xfs_repair information(just one AG): +agf_freeblks 0, counted 3224 in ag 0 +agf_longest 536874136, counted 3224 in ag 0 +sb_fdblocks 613, counted 3228 + +Test as follows: +mount tmp.img tmpdir +cp file1M tmpdir +sync + +In 4.19-stable, sync will stuck, the reason is: +xfs_mountfs +xfs_check_summary_counts +if ((!xfs_sb_version_haslazysbcount(&mp->m_sb) || +XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) && +!xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS)) +return 0; -->just return, incore sb_fdblocks still be 613 +xfs_initialize_perag_data + +cp file1M tmpdir -->ok(write file to pagecache) +sync -->stuck(write pagecache to disk) +xfs_map_blocks +xfs_iomap_write_allocate +while (count_fsb != 0) { +nimaps = 0; +while (nimaps == 0) { --> endless loop +nimaps = 1; +xfs_bmapi_write(..., &nimaps) --> nimaps becomes 0 again +xfs_bmapi_write +xfs_bmap_alloc +xfs_bmap_btalloc +xfs_alloc_vextent +xfs_alloc_fix_freelist +xfs_alloc_space_available -->fail(agf_freeblks is 0) + +In linux-next, sync not stuck, cause commit c2b3164320b5 ("xfs: +use the latest extent at writeback delalloc conversion time") remove +the above while, dmesg is as follows: +[ 55.250114] XFS (loop0): page discard on page ffffea0008bc7380, inode 0x1b0c, offset 0. + +Users do not know why this page is discard, the better soultion is: +1. Like xfs_repair, make sure sb_fdblocks is equal to counted +(xfs_initialize_perag_data did this, who is not called at this mount) +2. Add agf verify, if fail, will tell users to repair + +This patch use the second soultion. + +Signed-off-by: Zheng Bin +Signed-off-by: Ren Xudong +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_alloc.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c +index a92ca52..09db669 100644 +--- a/libxfs/xfs_alloc.c ++++ b/libxfs/xfs_alloc.c +@@ -2854,6 +2854,13 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp))) + return __this_address; + ++ if (be32_to_cpu(agf->agf_length) > mp->m_sb.sb_dblocks) ++ return __this_address; ++ ++ if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) || ++ be32_to_cpu(agf->agf_freeblks) > be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ + if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 || + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || +@@ -2865,6 +2872,10 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)) + return __this_address; + ++ if (xfs_sb_version_hasrmapbt(&mp->m_sb) && ++ be32_to_cpu(agf->agf_rmap_blocks) > be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ + /* + * during growfs operations, the perag is not fully initialised, + * so we can't use it for any useful checking. growfs ensures we can't +@@ -2879,6 +2890,11 @@ xfs_agf_verify( + return __this_address; + + if (xfs_sb_version_hasreflink(&mp->m_sb) && ++ be32_to_cpu(agf->agf_refcount_blocks) > ++ be32_to_cpu(agf->agf_length)) ++ return __this_address; ++ ++ if (xfs_sb_version_hasreflink(&mp->m_sb) && + (be32_to_cpu(agf->agf_refcount_level) < 1 || + be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)) + return __this_address; +-- +1.8.3.1 + diff --git a/0002-xfs-fix-an-undefined-behaviour-in-_da3_path_shift.patch b/0002-xfs-fix-an-undefined-behaviour-in-_da3_path_shift.patch new file mode 100644 index 0000000000000000000000000000000000000000..57d2b3887d6e42af1c4769ff77a655623b8f1cbe --- /dev/null +++ b/0002-xfs-fix-an-undefined-behaviour-in-_da3_path_shift.patch @@ -0,0 +1,67 @@ +From 397f529d466e9fcd2224631abf65b0a3c0166b4e Mon Sep 17 00:00:00 2001 +From: Qian Cai +Date: Wed, 29 Apr 2020 16:08:34 -0400 +Subject: [PATCH 02/16] xfs: fix an undefined behaviour in _da3_path_shift + +Source kernel commit: 4982bff1ace1196843f55536fcd4cc119738fe39 + +In xfs_da3_path_shift() "blk" can be assigned to state->path.blk[-1] if +state->path.active is 1 (which is a valid state) when it tries to add an +entry to a single dir leaf block and then to shift forward to see if +there's a sibling block that would be a better place to put the new +entry. This causes a UBSAN warning given negative array indices are +undefined behavior in C. In practice the warning is entirely harmless +given that "blk" is never dereferenced in this case, but it is still +better to fix up the warning and slightly improve the code. + +UBSAN: Undefined behaviour in fs/xfs/libxfs/xfs_da_btree.c:1989:14 +index -1 is out of range for type 'xfs_da_state_blk_t [5]' +Call trace: +dump_backtrace+0x0/0x2c8 +show_stack+0x20/0x2c +dump_stack+0xe8/0x150 +__ubsan_handle_out_of_bounds+0xe4/0xfc +xfs_da3_path_shift+0x860/0x86c [xfs] +xfs_da3_node_lookup_int+0x7c8/0x934 [xfs] +xfs_dir2_node_addname+0x2c8/0xcd0 [xfs] +xfs_dir_createname+0x348/0x38c [xfs] +xfs_create+0x6b0/0x8b4 [xfs] +xfs_generic_create+0x12c/0x1f8 [xfs] +xfs_vn_mknod+0x3c/0x4c [xfs] +xfs_vn_create+0x34/0x44 [xfs] +do_last+0xd4c/0x10c8 +path_openat+0xbc/0x2f4 +do_filp_open+0x74/0xf4 +do_sys_openat2+0x98/0x180 +__arm64_sys_openat+0xf8/0x170 +do_el0_svc+0x170/0x240 +el0_sync_handler+0x150/0x250 +el0_sync+0x164/0x180 + +Suggested-by: Christoph Hellwig +Signed-off-by: Qian Cai +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_da_btree.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c +index 3f40e99..7f26d12 100644 +--- a/libxfs/xfs_da_btree.c ++++ b/libxfs/xfs_da_btree.c +@@ -1983,7 +1983,8 @@ xfs_da3_path_shift( + ASSERT(path != NULL); + ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); + level = (path->active-1) - 1; /* skip bottom layer in path */ +- for (blk = &path->blk[level]; level >= 0; blk--, level--) { ++ for (; level >= 0; level--) { ++ blk = &path->blk[level]; + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, + blk->bp->b_addr); + +-- +1.8.3.1 + diff --git a/0003-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch b/0003-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch new file mode 100644 index 0000000000000000000000000000000000000000..4ebc725ecc07ef0dd0bff612c119f03fa46f1043 --- /dev/null +++ b/0003-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch @@ -0,0 +1,37 @@ +From a53b5f2f5f2ec70bc44a45d4b7c3ab2f2470cc0e Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 1 May 2020 17:37:09 -0400 +Subject: [PATCH 05/16] xfs: fix incorrect test in + xfs_alloc_ag_vextent_lastblock + +Source kernel commit: 77ca1eed5a7d2bf0905562eb1a15aac76bc19fe4 + +When I lifted the code in xfs_alloc_ag_vextent_lastblock out of a loop, +I forgot to convert all the accesses to len to be pointer dereferences. + +Coverity-id: 1457918 +Fixes: 5113f8ec3753ed ("xfs: clean up weird while loop in xfs_alloc_ag_vextent_near") +Signed-off-by: Darrick J. Wong +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_alloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c +index 09db669..58f4f07 100644 +--- a/libxfs/xfs_alloc.c ++++ b/libxfs/xfs_alloc.c +@@ -1511,7 +1511,7 @@ xfs_alloc_ag_vextent_lastblock( + * maxlen, go to the start of this block, and skip all those smaller + * than minlen. + */ +- if (len || args->alignment > 1) { ++ if (*len || args->alignment > 1) { + acur->cnt->bc_ptrs[0] = 1; + do { + error = xfs_alloc_get_rec(acur->cnt, bno, len, &i); +-- +1.8.3.1 + diff --git a/0004-xfs_db-fix-crc-invalidation-segfault.patch b/0004-xfs_db-fix-crc-invalidation-segfault.patch new file mode 100644 index 0000000000000000000000000000000000000000..232edb5eadb69e853f1ae07de75f2922072f257a --- /dev/null +++ b/0004-xfs_db-fix-crc-invalidation-segfault.patch @@ -0,0 +1,41 @@ +From 46ab86660a841a6ec5100d183f3881632a3055cf Mon Sep 17 00:00:00 2001 +From: Anthony Iliopoulos +Date: Tue, 26 May 2020 14:35:51 -0400 +Subject: [PATCH 06/16] xfs_db: fix crc invalidation segfault + +The nowrite_ops var is declared within nested block scope but used +outside that scope, causing xfs_db to crash while trying to defererence +the verify_write pointer. Fix it by lifting the declaration to the outer +scope, where it is accessed. + +Fixes: b64af2c48220c8 ("xfs_db: add crc manipulation commands") +Reviewed-by: Eric Sandeen +Signed-off-by: Anthony Iliopoulos +Signed-off-by: Eric Sandeen +--- + db/crc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/db/crc.c b/db/crc.c +index 95161c6..b23417a 100644 +--- a/db/crc.c ++++ b/db/crc.c +@@ -53,6 +53,7 @@ crc_f( + char **argv) + { + const struct xfs_buf_ops *stashed_ops = NULL; ++ struct xfs_buf_ops nowrite_ops; + extern char *progname; + const field_t *fields; + const ftattr_t *fa; +@@ -127,7 +128,6 @@ crc_f( + } + + if (invalidate) { +- struct xfs_buf_ops nowrite_ops; + flist_t *sfl; + int bit_length; + int parentoffset; +-- +1.8.3.1 + diff --git a/0005-xfs-fix-inode-allocation-block-res-calculation-prece.patch b/0005-xfs-fix-inode-allocation-block-res-calculation-prece.patch new file mode 100644 index 0000000000000000000000000000000000000000..0163c8f773f7d7afd6f88818a8981ede4783f1cf --- /dev/null +++ b/0005-xfs-fix-inode-allocation-block-res-calculation-prece.patch @@ -0,0 +1,45 @@ +From ebd6cdd32653b6f44ca270ea08571fb4fe1ad85f Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Fri, 4 Sep 2020 16:01:20 -0400 +Subject: [PATCH 10/16] xfs: fix inode allocation block res calculation + precedence + +Source kernel commit: b2a8864728683443f34a9fd33a2b78b860934cc1 + +The block reservation calculation for inode allocation is supposed +to consist of the blocks required for the inode chunk plus +(maxlevels-1) of the inode btree multiplied by the number of inode +btrees in the fs (2 when finobt is enabled, 1 otherwise). + +Instead, the macro returns (ialloc_blocks + 2) due to a precedence +error in the calculation logic. This leads to block reservation +overruns via generic/531 on small block filesystems with finobt +enabled. Add braces to fix the calculation and reserve the +appropriate number of blocks. + +Fixes: 9d43b180af67 ("xfs: update inode allocation/free transaction reservations for finobt") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_trans_space.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h +index 88221c7..c6df01a 100644 +--- a/libxfs/xfs_trans_space.h ++++ b/libxfs/xfs_trans_space.h +@@ -57,7 +57,7 @@ + XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) + #define XFS_IALLOC_SPACE_RES(mp) \ + (M_IGEO(mp)->ialloc_blks + \ +- (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \ ++ ((xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1) * \ + (M_IGEO(mp)->inobt_maxlevels - 1))) + + /* +-- +1.8.3.1 + diff --git a/0006-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch b/0006-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch new file mode 100644 index 0000000000000000000000000000000000000000..d2ec81749e45f3426c920324325dcfab55920a1f --- /dev/null +++ b/0006-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch @@ -0,0 +1,79 @@ +From de7d5664d0f7a4a29c32aa98331d965f6c5c6de8 Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Tue, 15 Sep 2020 15:59:38 -0400 +Subject: [PATCH 11/16] xfs: fix off-by-one in inode alloc block reservation + calculation + +Source kernel commit: 657f101930bc6c5b41bd7d6c22565c4302a80d33 + +The inode chunk allocation transaction reserves inobt_maxlevels-1 +blocks to accommodate a full split of the inode btree. A full split +requires an allocation for every existing level and a new root +block, which means inobt_maxlevels is the worst case block +requirement for a transaction that inserts to the inobt. This can +lead to a transaction block reservation overrun when tmpfile +creation allocates an inode chunk and expands the inobt to its +maximum depth. This problem has been observed in conjunction with +overlayfs, which makes frequent use of tmpfiles internally. + +The existing reservation code goes back as far as the Linux git repo +history (v2.6.12). It was likely never observed as a problem because +the traditional file/directory creation transactions also include +worst case block reservation for directory modifications, which most +likely is able to make up for a single block deficiency in the inode +allocation portion of the calculation. tmpfile support is relatively +more recent (v3.15), less heavily used, and only includes the inode +allocation block reservation as tmpfiles aren't linked into the +directory tree on creation. + +Fix up the inode alloc block reservation macro and a couple of the +block allocator minleft parameters that enforce an allocation to +leave enough free blocks in the AG for a full inobt split. + +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_ialloc.c | 4 ++-- + libxfs/xfs_trans_space.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c +index 00b3326..750b223 100644 +--- a/libxfs/xfs_ialloc.c ++++ b/libxfs/xfs_ialloc.c +@@ -683,7 +683,7 @@ xfs_ialloc_ag_alloc( + args.minalignslop = igeo->cluster_align - 1; + + /* Allow space for the inode btree to split. */ +- args.minleft = igeo->inobt_maxlevels - 1; ++ args.minleft = igeo->inobt_maxlevels; + if ((error = xfs_alloc_vextent(&args))) + return error; + +@@ -731,7 +731,7 @@ xfs_ialloc_ag_alloc( + /* + * Allow space for the inode btree to split. + */ +- args.minleft = igeo->inobt_maxlevels - 1; ++ args.minleft = igeo->inobt_maxlevels; + if ((error = xfs_alloc_vextent(&args))) + return error; + } +diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h +index c6df01a..7ad3659 100644 +--- a/libxfs/xfs_trans_space.h ++++ b/libxfs/xfs_trans_space.h +@@ -58,7 +58,7 @@ + #define XFS_IALLOC_SPACE_RES(mp) \ + (M_IGEO(mp)->ialloc_blks + \ + ((xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1) * \ +- (M_IGEO(mp)->inobt_maxlevels - 1))) ++ M_IGEO(mp)->inobt_maxlevels)) + + /* + * Space reservation values for various transactions. +-- +1.8.3.1 + diff --git a/0007-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch b/0007-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch new file mode 100644 index 0000000000000000000000000000000000000000..3bedd5faa2aa50a48b8df4295fc8492f95dc2d40 --- /dev/null +++ b/0007-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch @@ -0,0 +1,52 @@ +From 9182dbe5d9667454d782e334de483c8ff48ab102 Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Tue, 15 Sep 2020 15:59:38 -0400 +Subject: [PATCH 12/16] xfs: fix boundary test in xfs_attr_shortform_verify + +Source kernel commit: f4020438fab05364018c91f7e02ebdd192085933 + +The boundary test for the fixed-offset parts of xfs_attr_sf_entry in +xfs_attr_shortform_verify is off by one, because the variable array +at the end is defined as nameval[1] not nameval[]. +Hence we need to subtract 1 from the calculation. + +This can be shown by: + +# touch file +# setfattr -n root.a file + +and verifications will fail when it's written to disk. + +This only matters for a last attribute which has a single-byte name +and no value, otherwise the combination of namelen & valuelen will +push endp further out and this test won't fail. + +Fixes: 1e1bbd8e7ee06 ("xfs: create structure verifier function for shortform xattrs") +Signed-off-by: Eric Sandeen +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_attr_leaf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c +index 541a1ff..cca10ff 100644 +--- a/libxfs/xfs_attr_leaf.c ++++ b/libxfs/xfs_attr_leaf.c +@@ -1007,8 +1007,10 @@ xfs_attr_shortform_verify( + * struct xfs_attr_sf_entry has a variable length. + * Check the fixed-offset parts of the structure are + * within the data buffer. ++ * xfs_attr_sf_entry is defined with a 1-byte variable ++ * array at the end, so we must subtract that off. + */ +- if (((char *)sfep + sizeof(*sfep)) >= endp) ++ if (((char *)sfep + sizeof(*sfep) - 1) >= endp) + return __this_address; + + /* Don't allow names with known bad length. */ +-- +1.8.3.1 + diff --git a/0008-xfs-fix-xfs_bmap_validate_extent_raw-when-checking-a.patch b/0008-xfs-fix-xfs_bmap_validate_extent_raw-when-checking-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..404358a4837c85b6fa27103bc054cd4e8c27ff0a --- /dev/null +++ b/0008-xfs-fix-xfs_bmap_validate_extent_raw-when-checking-a.patch @@ -0,0 +1,35 @@ +From 601bb251c71860fbbf2b8054a6b4ac46d80c00d8 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 17 Sep 2020 10:16:02 -0400 +Subject: [PATCH 13/16] xfs: fix xfs_bmap_validate_extent_raw when checking + attr fork of rt files + +Source kernel commit: d0c20d38af135b2b4b90aa59df7878ef0c8fbef4 + +The realtime flag only applies to the data fork, so don't use the +realtime block number checks on the attr fork of a realtime file. + +Fixes: 30b0984d9117 ("xfs: refactor bmap record validation") +Signed-off-by: Darrick J. Wong +Reviewed-by: Eric Sandeen +Signed-off-by: Eric Sandeen +--- + libxfs/xfs_bmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c +index d43155d..219ae27 100644 +--- a/libxfs/xfs_bmap.c ++++ b/libxfs/xfs_bmap.c +@@ -6291,7 +6291,7 @@ xfs_bmap_validate_extent( + + isrt = XFS_IS_REALTIME_INODE(ip); + endfsb = irec->br_startblock + irec->br_blockcount - 1; +- if (isrt) { ++ if (isrt && whichfork == XFS_DATA_FORK) { + if (!xfs_verify_rtbno(mp, irec->br_startblock)) + return __this_address; + if (!xfs_verify_rtbno(mp, endfsb)) +-- +1.8.3.1 + diff --git a/0009-xfs_repair-fix-error-in-process_sf_dir2_fixi8.patch b/0009-xfs_repair-fix-error-in-process_sf_dir2_fixi8.patch new file mode 100644 index 0000000000000000000000000000000000000000..554aca875fa2cdf4f67b7d58ffc958b2ceaed51e --- /dev/null +++ b/0009-xfs_repair-fix-error-in-process_sf_dir2_fixi8.patch @@ -0,0 +1,41 @@ +From c1f6f901b402278f3fcd08000e0579e346167ef6 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 28 Sep 2020 17:35:37 -0400 +Subject: [PATCH 14/16] xfs_repair: fix error in process_sf_dir2_fixi8 + +The goal of process_sf_dir2_fixi8 is to convert an i8 shortform +directory into a (shorter) i4 shortform directory. It achieves this by +duplicating the old sf directory contents (as oldsfp), zeroing i8count +in the caller's directory buffer (i.e. newsfp/sfp), and reinitializing +the new directory with the old directory's entries. + +Unfortunately, it copies the parent pointer from sfp (the buffer we've +already started changing), not oldsfp. This leads to directory +corruption since at that point we zeroed i8count, which means that we +save only the upper four bytes from the parent pointer entry. + +This was found by fuzzing u3.sfdir3.hdr.i8count = ones in xfs/384. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Signed-off-by: Eric Sandeen +--- + repair/dir2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/repair/dir2.c b/repair/dir2.c +index cbbce60..d0daff7 100644 +--- a/repair/dir2.c ++++ b/repair/dir2.c +@@ -84,7 +84,7 @@ process_sf_dir2_fixi8( + memmove(oldsfp, newsfp, oldsize); + newsfp->count = oldsfp->count; + newsfp->i8count = 0; +- ino = libxfs_dir2_sf_get_parent_ino(sfp); ++ ino = libxfs_dir2_sf_get_parent_ino(oldsfp); + libxfs_dir2_sf_put_parent_ino(newsfp, ino); + oldsfep = xfs_dir2_sf_firstentry(oldsfp); + newsfep = xfs_dir2_sf_firstentry(newsfp); +-- +1.8.3.1 + diff --git a/0010-libfrog-fix-a-potential-null-pointer-dereference.patch b/0010-libfrog-fix-a-potential-null-pointer-dereference.patch new file mode 100644 index 0000000000000000000000000000000000000000..beb93118cf3dcb99d354021f1cb567c115b2b66b --- /dev/null +++ b/0010-libfrog-fix-a-potential-null-pointer-dereference.patch @@ -0,0 +1,36 @@ +From 1741c05193b561c01a7532d9536f3a8033102684 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 12 Oct 2020 11:59:19 -0400 +Subject: [PATCH 15/16] libfrog: fix a potential null pointer dereference + +Apparently, gcc 10.2 thinks that it's possible for either of the calloc +arguments to be zero here, in which case it will return NULL with a zero +errno. I suppose it's possible to do that via integer overflow in the +macro, though I find it unlikely unless someone passes in a yuuuge value. + +Nevertheless, just shut up the warning by hardcoding the error number +so I can move on to nastier bugs. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Eric Sandeen +Signed-off-by: Eric Sandeen +--- + libfrog/bulkstat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c +index c3e5c5f..195f6ea 100644 +--- a/libfrog/bulkstat.c ++++ b/libfrog/bulkstat.c +@@ -428,7 +428,7 @@ xfrog_bulkstat_alloc_req( + + breq = calloc(1, XFS_BULKSTAT_REQ_SIZE(nr)); + if (!breq) +- return -errno; ++ return -ENOMEM; + + breq->hdr.icount = nr; + breq->hdr.ino = startino; +-- +1.8.3.1 + diff --git a/0011-libhandle-fix-potential-unterminated-string-problem.patch b/0011-libhandle-fix-potential-unterminated-string-problem.patch new file mode 100644 index 0000000000000000000000000000000000000000..7ad7b9e0ae26895d9cd3701f055739a22fc91aad --- /dev/null +++ b/0011-libhandle-fix-potential-unterminated-string-problem.patch @@ -0,0 +1,34 @@ +From 62be9551c3656effc2e013da12c9e1c9698c104f Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 12 Oct 2020 11:59:19 -0400 +Subject: [PATCH 16/16] libhandle: fix potential unterminated string problem + +gcc 10.2 complains about the strncpy call here, since it's possible that +the source string is so long that the fspath inside the fdhash structure +will end up without a null terminator. Work around strncpy braindamage +yet again by forcing the string to be terminated properly. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Eric Sandeen +Signed-off-by: Eric Sandeen +--- + libhandle/handle.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libhandle/handle.c b/libhandle/handle.c +index eb099f4..5c1686b 100644 +--- a/libhandle/handle.c ++++ b/libhandle/handle.c +@@ -107,7 +107,8 @@ path_to_fshandle( + } + + fdhp->fsfd = fd; +- strncpy(fdhp->fspath, fspath, sizeof(fdhp->fspath)); ++ strncpy(fdhp->fspath, fspath, sizeof(fdhp->fspath) - 1); ++ fdhp->fspath[sizeof(fdhp->fspath) - 1] = 0; + memcpy(fdhp->fsh, *fshanp, FSIDSIZE); + + fdhp->fnxt = fdhash_head; +-- +1.8.3.1 + diff --git a/xfsprogs.spec b/xfsprogs.spec index 1b7dd97f3cb19cccee037a0ed8ded80ad246ae72..7767d0f5aa26da9a15abc2071262b475095b0e45 100644 --- a/xfsprogs.spec +++ b/xfsprogs.spec @@ -1,11 +1,22 @@ Name: xfsprogs Version: 5.6.0 -Release: 2 +Release: 3 Summary: Administration and debugging tools for the XFS file system License: GPL+ and LGPLv2+ URL: https://xfs.wiki.kernel.org Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz +Patch1: 0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch +Patch2: 0002-xfs-fix-an-undefined-behaviour-in-_da3_path_shift.patch +Patch3: 0003-xfs-fix-incorrect-test-in-xfs_alloc_ag_vextent_lastb.patch +Patch4: 0004-xfs_db-fix-crc-invalidation-segfault.patch +Patch5: 0005-xfs-fix-inode-allocation-block-res-calculation-prece.patch +Patch6: 0006-xfs-fix-off-by-one-in-inode-alloc-block-reservation-.patch +Patch7: 0007-xfs-fix-boundary-test-in-xfs_attr_shortform_verify.patch +Patch8: 0008-xfs-fix-xfs_bmap_validate_extent_raw-when-checking-a.patch +Patch9: 0009-xfs_repair-fix-error-in-process_sf_dir2_fixi8.patch +Patch10: 0010-libfrog-fix-a-potential-null-pointer-dereference.patch +Patch11: 0011-libhandle-fix-potential-unterminated-string-problem.patch BuildRequires: libtool libattr-devel libuuid-devel gcc git BuildRequires: readline-devel libblkid-devel >= 2.30 lvm2-devel libicu-devel >= 62.0 @@ -99,6 +110,9 @@ rm -rf %{buildroot}%{_datadir}/doc/xfsprogs/ %changelog +* Tue Dec 2 2020 lixiaokeng - 5.6.0-3 +- backport patch from epoch2 + * Wed Nov 25 2020 haowenchao - 5.6.0-2 - Split xfsprogs-xfs_scrub and the xfsprogs recommends it.