From ba3a5f47deaad7d5e7786052d9654b5a98a87938 Mon Sep 17 00:00:00 2001 From: "Justin M. Forbes" Date: Thu, 14 May 2020 12:50:57 -0500 Subject: Linux v5.6.13 --- ...d-agf-freeblocks-verify-in-xfs_agf_verify.patch | 107 +++++++++++++++++++++ kernel.spec | 13 ++- sources | 2 +- ...vent-log-version-before-reading-final-eve.patch | 81 ++++++++++++++++ 4 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch create mode 100644 tpm-check-event-log-version-before-reading-final-eve.patch 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 000000000..8409a1f30 --- /dev/null +++ b/0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch @@ -0,0 +1,107 @@ +From d0c7feaf87678371c2c09b3709400be416b2dc62 Mon Sep 17 00:00:00 2001 +From: Zheng Bin +Date: Fri, 21 Feb 2020 07:38:20 -0800 +Subject: [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify + +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 +--- + fs/xfs/libxfs/xfs_alloc.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c +index d8053bc96c4d..183dc2587092 100644 +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -2858,6 +2858,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 || +@@ -2869,6 +2876,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 +@@ -2882,6 +2893,11 @@ xfs_agf_verify( + be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) + 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)) +-- +2.26.2 + diff --git a/kernel.spec b/kernel.spec index 60d5c4d05..082527de7 100644 --- a/kernel.spec +++ b/kernel.spec @@ -89,7 +89,7 @@ Summary: The Linux kernel %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 12 +%define stable_update 13 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -901,6 +901,12 @@ Patch512: drm-dp_mst-Fix-drm_dp_send_dpcd_write-return-code.patch # CVE-2020-10711 rhbz 1825116 1834778 Patch513: net-netlabel-cope-with-NULL-catmap.patch +#rhbz 1779611 +Patch514: tpm-check-event-log-version-before-reading-final-eve.patch + +# CVE-2020-12655 rhbz 1832543 1832545 +Patch515: 0001-xfs-add-agf-freeblocks-verify-in-xfs_agf_verify.patch + # END OF PATCH DEFINITIONS %endif @@ -2931,6 +2937,11 @@ fi # # %changelog +* Thu May 14 2020 Justin M. Forbes - 5.6.13-200 +- Linux v5.6.13 +- Fix boot hang caused by buggy TPM support (rhbz 1779611) +- Fix CVE-2020-12655 (rhbz 1832543 1832545) + * Tue May 12 2020 Justin M. Forbes - Fix CVE-2020-10711 (rhbz 1825116 1834778) diff --git a/sources b/sources index ebd905da4..f184fd65a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (linux-5.6.tar.xz) = 80846fe2b4e4a7ff471d2dde28a8216ae807a3209f959e93d39ea4fc9a189ea28ec3db9d303b3fe15a28c2cb90e7446876678e93e23353c2d6f262e364a06bc9 -SHA512 (patch-5.6.12.xz) = e057961567d8482482ce8e27467b4fc47ddff604a3fd47f5e4f4092a29cc9ef5d180dd739f3edff91ab373108b699c04e55131722e8d4f153f4dd7e7833b48cd +SHA512 (patch-5.6.13.xz) = 10eabe59db21b0d82932b8122d3f07f12aec435900350a6d7f3e281676a1036860e24284252425c5b08fea02215166e3f65c49e5b4af8dbb7e03bcfbc6a86148 diff --git a/tpm-check-event-log-version-before-reading-final-eve.patch b/tpm-check-event-log-version-before-reading-final-eve.patch new file mode 100644 index 000000000..9668c807b --- /dev/null +++ b/tpm-check-event-log-version-before-reading-final-eve.patch @@ -0,0 +1,81 @@ +From MAILER-DAEMON Thu May 14 17:38:32 2020 +From: Loïc Yhuel +To: linux-integrity@vger.kernel.org +Cc: matthewgarrett@google.com, ardb@kernel.org, jarkko.sakkinen@linux.intel.com, javierm@redhat.com, Loïc Yhuel +Subject: [PATCH] tpm: check event log version before reading final events +Date: Tue, 12 May 2020 06:01:13 +0200 +Message-Id: <20200512040113.277768-1-loic.yhuel@gmail.com> +Sender: linux-integrity-owner@vger.kernel.org +List-ID: +X-Mailing-List: linux-integrity@vger.kernel.org +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +This fixes the boot issues since 5.3 on several Dell models when the TPM +is enabled. Depending on the exact grub binary, booting the kernel would +freeze early, or just report an error parsing the final events log. + +We get an event log in the SHA-1 format, which doesn't have a +tcg_efi_specid_event_head in the first event, and there is a final events +table which doesn't match the crypto agile format. +__calc_tpm2_event_size reads bad "count" and "efispecid->num_algs", and +either fails, or loops long enough for the machine to be appear frozen. + +So we now only parse the final events table, which is per the spec always +supposed to be in the crypto agile format, when we got a event log in this +format. + +Fixes: 166a2809d65b2 ("tpm: Don't duplicate events from the final event log in the TCG2 log") +Fixes: c46f3405692de ("tpm: Reserve the TPM final events table") +Signed-off-by: Loïc Yhuel +Reviewed-by: Javier Martinez Canillas +Reviewed-by: Jerry Snitselaar +Reviewed-by: Matthew Garrett +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1779611 +--- + drivers/firmware/efi/libstub/tpm.c | 5 +++-- + drivers/firmware/efi/tpm.c | 3 ++- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c +index 1d59e103a2e3..e9a684637b70 100644 +--- a/drivers/firmware/efi/libstub/tpm.c ++++ b/drivers/firmware/efi/libstub/tpm.c +@@ -54,7 +54,7 @@ void efi_retrieve_tpm2_eventlog(void) + efi_status_t status; + efi_physical_addr_t log_location = 0, log_last_entry = 0; + struct linux_efi_tpm_eventlog *log_tbl = NULL; +- struct efi_tcg2_final_events_table *final_events_table; ++ struct efi_tcg2_final_events_table *final_events_table = NULL; + unsigned long first_entry_addr, last_entry_addr; + size_t log_size, last_entry_size; + efi_bool_t truncated; +@@ -127,7 +127,8 @@ void efi_retrieve_tpm2_eventlog(void) + * Figure out whether any events have already been logged to the + * final events structure, and if so how much space they take up + */ +- final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); ++ if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) ++ final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); + if (final_events_table && final_events_table->nr_events) { + struct tcg_pcr_event2_head *header; + int offset; +diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c +index 55b031d2c989..77e101a395e7 100644 +--- a/drivers/firmware/efi/tpm.c ++++ b/drivers/firmware/efi/tpm.c +@@ -62,7 +62,8 @@ int __init efi_tpm_eventlog_init(void) + tbl_size = sizeof(*log_tbl) + log_tbl->size; + memblock_reserve(efi.tpm_log, tbl_size); + +- if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) ++ if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || ++ log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + goto out; + + final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl)); +-- +2.26.2 + + -- cgit