From 04f14f429dca01a75606d8ee221ee0f0809b0151 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 7 Jun 2023 20:41:18 +0200 Subject: [PATCH] 6.1-stable patches added patches: arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch xfs-verify-buffer-contents-when-we-skip-log-replay.patch --- ...ssor-version-to-key-off-ampere-quirk.patch | 173 ++++++++++++++++++ queue-6.1/series | 3 + ...-t-use-gfp_kernel-in-softirq-context.patch | 45 +++++ ...fer-contents-when-we-skip-log-replay.patch | 113 ++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 queue-6.1/arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch create mode 100644 queue-6.1/tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch create mode 100644 queue-6.1/xfs-verify-buffer-contents-when-we-skip-log-replay.patch diff --git a/queue-6.1/arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch b/queue-6.1/arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch new file mode 100644 index 00000000000..84cb83a3c3a --- /dev/null +++ b/queue-6.1/arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch @@ -0,0 +1,173 @@ +From eb684408f3ea4856639675d6465f0024e498e4b1 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Tue, 28 Feb 2023 17:00:49 +0100 +Subject: arm64: efi: Use SMBIOS processor version to key off Ampere quirk + +From: Ard Biesheuvel + +commit eb684408f3ea4856639675d6465f0024e498e4b1 upstream. + +Instead of using the SMBIOS type 1 record 'family' field, which is often +modified by OEMs, use the type 4 'processor ID' and 'processor version' +fields, which are set to a small set of probe-able values on all known +Ampere EFI systems in the field. + +Fixes: 550b33cfd4452968 ("arm64: efi: Force the use of ...") +Tested-by: Andrea Righi +Signed-off-by: Ard Biesheuvel +Signed-off-by: Jeremi Piotrowski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/libstub/arm64-stub.c | 39 ++++++++++++++++++++++------ + drivers/firmware/efi/libstub/efistub.h | 41 +++++++++++++++++++++++++++--- + drivers/firmware/efi/libstub/smbios.c | 13 ++++++++- + 3 files changed, 80 insertions(+), 13 deletions(-) + +--- a/drivers/firmware/efi/libstub/arm64-stub.c ++++ b/drivers/firmware/efi/libstub/arm64-stub.c +@@ -17,20 +17,43 @@ + + static bool system_needs_vamap(void) + { +- const u8 *type1_family = efi_get_smbios_string(1, family); ++ const struct efi_smbios_type4_record *record; ++ const u32 __aligned(1) *socid; ++ const u8 *version; + + /* + * Ampere eMAG, Altra, and Altra Max machines crash in SetTime() if +- * SetVirtualAddressMap() has not been called prior. ++ * SetVirtualAddressMap() has not been called prior. Most Altra systems ++ * can be identified by the SMCCC soc ID, which is conveniently exposed ++ * via the type 4 SMBIOS records. Otherwise, test the processor version ++ * field. eMAG systems all appear to have the processor version field ++ * set to "eMAG". + */ +- if (!type1_family || ( +- strcmp(type1_family, "eMAG") && +- strcmp(type1_family, "Altra") && +- strcmp(type1_family, "Altra Max"))) ++ record = (struct efi_smbios_type4_record *)efi_get_smbios_record(4); ++ if (!record) + return false; + +- efi_warn("Working around broken SetVirtualAddressMap()\n"); +- return true; ++ socid = (u32 *)record->processor_id; ++ switch (*socid & 0xffff000f) { ++ static char const altra[] = "Ampere(TM) Altra(TM) Processor"; ++ static char const emag[] = "eMAG"; ++ ++ default: ++ version = efi_get_smbios_string(&record->header, 4, ++ processor_version); ++ if (!version || (strncmp(version, altra, sizeof(altra) - 1) && ++ strncmp(version, emag, sizeof(emag) - 1))) ++ break; ++ ++ fallthrough; ++ ++ case 0x0a160001: // Altra ++ case 0x0a160002: // Altra Max ++ efi_warn("Working around broken SetVirtualAddressMap()\n"); ++ return true; ++ } ++ ++ return false; + } + + efi_status_t check_platform_features(void) +--- a/drivers/firmware/efi/libstub/efistub.h ++++ b/drivers/firmware/efi/libstub/efistub.h +@@ -983,6 +983,8 @@ struct efi_smbios_record { + u16 handle; + }; + ++const struct efi_smbios_record *efi_get_smbios_record(u8 type); ++ + struct efi_smbios_type1_record { + struct efi_smbios_record header; + +@@ -996,13 +998,46 @@ struct efi_smbios_type1_record { + u8 family; + }; + +-#define efi_get_smbios_string(__type, __name) ({ \ ++struct efi_smbios_type4_record { ++ struct efi_smbios_record header; ++ ++ u8 socket; ++ u8 processor_type; ++ u8 processor_family; ++ u8 processor_manufacturer; ++ u8 processor_id[8]; ++ u8 processor_version; ++ u8 voltage; ++ u16 external_clock; ++ u16 max_speed; ++ u16 current_speed; ++ u8 status; ++ u8 processor_upgrade; ++ u16 l1_cache_handle; ++ u16 l2_cache_handle; ++ u16 l3_cache_handle; ++ u8 serial_number; ++ u8 asset_tag; ++ u8 part_number; ++ u8 core_count; ++ u8 enabled_core_count; ++ u8 thread_count; ++ u16 processor_characteristics; ++ u16 processor_family2; ++ u16 core_count2; ++ u16 enabled_core_count2; ++ u16 thread_count2; ++ u16 thread_enabled; ++}; ++ ++#define efi_get_smbios_string(__record, __type, __name) ({ \ + int size = sizeof(struct efi_smbios_type ## __type ## _record); \ + int off = offsetof(struct efi_smbios_type ## __type ## _record, \ + __name); \ +- __efi_get_smbios_string(__type, off, size); \ ++ __efi_get_smbios_string((__record), __type, off, size); \ + }) + +-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize); ++const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record, ++ u8 type, int offset, int recsize); + + #endif +--- a/drivers/firmware/efi/libstub/smbios.c ++++ b/drivers/firmware/efi/libstub/smbios.c +@@ -22,19 +22,28 @@ struct efi_smbios_protocol { + u8 minor_version; + }; + +-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize) ++const struct efi_smbios_record *efi_get_smbios_record(u8 type) + { + struct efi_smbios_record *record; + efi_smbios_protocol_t *smbios; + efi_status_t status; + u16 handle = 0xfffe; +- const u8 *strtable; + + status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL, + (void **)&smbios) ?: + efi_call_proto(smbios, get_next, &handle, &type, &record, NULL); + if (status != EFI_SUCCESS) + return NULL; ++ return record; ++} ++ ++const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record, ++ u8 type, int offset, int recsize) ++{ ++ const u8 *strtable; ++ ++ if (!record) ++ return NULL; + + strtable = (u8 *)record + record->length; + for (int i = 1; i < ((u8 *)record)[offset]; i++) { diff --git a/queue-6.1/series b/queue-6.1/series index e6914a0216c..3d1d8f111d3 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -225,3 +225,6 @@ regmap-account-for-register-length-when-chunking.patch tpm-tpm_tis-request-threaded-interrupt-handler.patch iommu-amd-pgtbl_v2-fix-domain-max-address.patch drm-amd-display-have-payload-properly-created-after-resume.patch +xfs-verify-buffer-contents-when-we-skip-log-replay.patch +tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch +arm64-efi-use-smbios-processor-version-to-key-off-ampere-quirk.patch diff --git a/queue-6.1/tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch b/queue-6.1/tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch new file mode 100644 index 00000000000..21f723594c7 --- /dev/null +++ b/queue-6.1/tls-rx-strp-don-t-use-gfp_kernel-in-softirq-context.patch @@ -0,0 +1,45 @@ +From 74836ec828fe17b63f2006fdbf53311d691396bf Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Tue, 16 May 2023 18:50:42 -0700 +Subject: tls: rx: strp: don't use GFP_KERNEL in softirq context + +From: Jakub Kicinski + +commit 74836ec828fe17b63f2006fdbf53311d691396bf upstream. + +When receive buffer is small, or the TCP rx queue looks too +complicated to bother using it directly - we allocate a new +skb and copy data into it. + +We already use sk->sk_allocation... but nothing actually +sets it to GFP_ATOMIC on the ->sk_data_ready() path. + +Users of HW offload are far more likely to experience problems +due to scheduling while atomic. "Copy mode" is very rarely +triggered with SW crypto. + +Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser") +Tested-by: Shai Amiram +Signed-off-by: Jakub Kicinski +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -2289,8 +2289,12 @@ static void tls_data_ready(struct sock * + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); + struct sk_psock *psock; ++ gfp_t alloc_save; + ++ alloc_save = sk->sk_allocation; ++ sk->sk_allocation = GFP_ATOMIC; + tls_strp_data_ready(&ctx->strp); ++ sk->sk_allocation = alloc_save; + + psock = sk_psock_get(sk); + if (psock) { diff --git a/queue-6.1/xfs-verify-buffer-contents-when-we-skip-log-replay.patch b/queue-6.1/xfs-verify-buffer-contents-when-we-skip-log-replay.patch new file mode 100644 index 00000000000..21b32f505d9 --- /dev/null +++ b/queue-6.1/xfs-verify-buffer-contents-when-we-skip-log-replay.patch @@ -0,0 +1,113 @@ +From 22ed903eee23a5b174e240f1cdfa9acf393a5210 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Wed, 12 Apr 2023 15:49:23 +1000 +Subject: xfs: verify buffer contents when we skip log replay + +From: Darrick J. Wong + +commit 22ed903eee23a5b174e240f1cdfa9acf393a5210 upstream. + +syzbot detected a crash during log recovery: + +XFS (loop0): Mounting V5 Filesystem bfdc47fc-10d8-4eed-a562-11a831b3f791 +XFS (loop0): Torn write (CRC failure) detected at log block 0x180. Truncating head block from 0x200. +XFS (loop0): Starting recovery (logdev: internal) +================================================================== +BUG: KASAN: slab-out-of-bounds in xfs_btree_lookup_get_block+0x15c/0x6d0 fs/xfs/libxfs/xfs_btree.c:1813 +Read of size 8 at addr ffff88807e89f258 by task syz-executor132/5074 + +CPU: 0 PID: 5074 Comm: syz-executor132 Not tainted 6.2.0-rc1-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x1b1/0x290 lib/dump_stack.c:106 + print_address_description+0x74/0x340 mm/kasan/report.c:306 + print_report+0x107/0x1f0 mm/kasan/report.c:417 + kasan_report+0xcd/0x100 mm/kasan/report.c:517 + xfs_btree_lookup_get_block+0x15c/0x6d0 fs/xfs/libxfs/xfs_btree.c:1813 + xfs_btree_lookup+0x346/0x12c0 fs/xfs/libxfs/xfs_btree.c:1913 + xfs_btree_simple_query_range+0xde/0x6a0 fs/xfs/libxfs/xfs_btree.c:4713 + xfs_btree_query_range+0x2db/0x380 fs/xfs/libxfs/xfs_btree.c:4953 + xfs_refcount_recover_cow_leftovers+0x2d1/0xa60 fs/xfs/libxfs/xfs_refcount.c:1946 + xfs_reflink_recover_cow+0xab/0x1b0 fs/xfs/xfs_reflink.c:930 + xlog_recover_finish+0x824/0x920 fs/xfs/xfs_log_recover.c:3493 + xfs_log_mount_finish+0x1ec/0x3d0 fs/xfs/xfs_log.c:829 + xfs_mountfs+0x146a/0x1ef0 fs/xfs/xfs_mount.c:933 + xfs_fs_fill_super+0xf95/0x11f0 fs/xfs/xfs_super.c:1666 + get_tree_bdev+0x400/0x620 fs/super.c:1282 + vfs_get_tree+0x88/0x270 fs/super.c:1489 + do_new_mount+0x289/0xad0 fs/namespace.c:3145 + do_mount fs/namespace.c:3488 [inline] + __do_sys_mount fs/namespace.c:3697 [inline] + __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7f89fa3f4aca +Code: 83 c4 08 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007fffd5fb5ef8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5 +RAX: ffffffffffffffda RBX: 00646975756f6e2c RCX: 00007f89fa3f4aca +RDX: 0000000020000100 RSI: 0000000020009640 RDI: 00007fffd5fb5f10 +RBP: 00007fffd5fb5f10 R08: 00007fffd5fb5f50 R09: 000000000000970d +R10: 0000000000200800 R11: 0000000000000206 R12: 0000000000000004 +R13: 0000555556c6b2c0 R14: 0000000000200800 R15: 00007fffd5fb5f50 + + +The fuzzed image contains an AGF with an obviously garbage +agf_refcount_level value of 32, and a dirty log with a buffer log item +for that AGF. The ondisk AGF has a higher LSN than the recovered log +item. xlog_recover_buf_commit_pass2 reads the buffer, compares the +LSNs, and decides to skip replay because the ondisk buffer appears to be +newer. + +Unfortunately, the ondisk buffer is corrupt, but recovery just read the +buffer with no buffer ops specified: + + error = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, + buf_f->blf_len, buf_flags, &bp, NULL); + +Skipping the buffer leaves its contents in memory unverified. This sets +us up for a kernel crash because xfs_refcount_recover_cow_leftovers +reads the buffer (which is still around in XBF_DONE state, so no read +verification) and creates a refcountbt cursor of height 32. This is +impossible so we run off the end of the cursor object and crash. + +Fix this by invoking the verifier on all skipped buffers and aborting +log recovery if the ondisk buffer is corrupt. It might be smarter to +force replay the log item atop the buffer and then see if it'll pass the +write verifier (like ext4 does) but for now let's go with the +conservative option where we stop immediately. + +Link: https://syzkaller.appspot.com/bug?extid=7e9494b8b399902e994e +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Reported-by: Danila Chernetsov +Link: https://lore.kernel.org/linux-xfs/20230601164439.15404-1-listdansp@mail.ru +Signed-off-by: Amir Goldstein +Acked-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_buf_item_recover.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/fs/xfs/xfs_buf_item_recover.c ++++ b/fs/xfs/xfs_buf_item_recover.c +@@ -943,6 +943,16 @@ xlog_recover_buf_commit_pass2( + if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { + trace_xfs_log_recover_buf_skip(log, buf_f); + xlog_recover_validate_buf_type(mp, bp, buf_f, NULLCOMMITLSN); ++ ++ /* ++ * We're skipping replay of this buffer log item due to the log ++ * item LSN being behind the ondisk buffer. Verify the buffer ++ * contents since we aren't going to run the write verifier. ++ */ ++ if (bp->b_ops) { ++ bp->b_ops->verify_read(bp); ++ error = bp->b_error; ++ } + goto out_release; + } + -- 2.47.3