From: Greg Kroah-Hartman Date: Sun, 22 Jan 2023 13:50:23 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.14.304~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1bb3640ab6693c4fb80210d07baea359e46fa997;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch cifs-reduce-roundtrips-on-create-qinfo-requests.patch efi-rt-wrapper-add-missing-include.patch fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch --- diff --git a/queue-6.1/arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch b/queue-6.1/arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch new file mode 100644 index 00000000000..7a83d887ea9 --- /dev/null +++ b/queue-6.1/arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch @@ -0,0 +1,126 @@ +From ff7a167961d1b97e0e205f245f806e564d3505e7 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Mon, 5 Dec 2022 11:31:25 +0100 +Subject: arm64: efi: Execute runtime services from a dedicated stack + +From: Ard Biesheuvel + +commit ff7a167961d1b97e0e205f245f806e564d3505e7 upstream. + +With the introduction of PRMT in the ACPI subsystem, the EFI rts +workqueue is no longer the only caller of efi_call_virt_pointer() in the +kernel. This means the EFI runtime services lock is no longer sufficient +to manage concurrent calls into firmware, but also that firmware calls +may occur that are not marshalled via the workqueue mechanism, but +originate directly from the caller context. + +For added robustness, and to ensure that the runtime services have 8 KiB +of stack space available as per the EFI spec, introduce a spinlock +protected EFI runtime stack of 8 KiB, where the spinlock also ensures +serialization between the EFI rts workqueue (which itself serializes EFI +runtime calls) and other callers of efi_call_virt_pointer(). + +While at it, use the stack pivot to avoid reloading the shadow call +stack pointer from the ordinary stack, as doing so could produce a +gadget to defeat it. + +Signed-off-by: Ard Biesheuvel +Cc: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/efi.h | 3 +++ + arch/arm64/kernel/efi-rt-wrapper.S | 13 ++++++++++++- + arch/arm64/kernel/efi.c | 27 +++++++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 1 deletion(-) + +--- a/arch/arm64/include/asm/efi.h ++++ b/arch/arm64/include/asm/efi.h +@@ -25,6 +25,7 @@ int efi_set_mapping_permissions(struct m + ({ \ + efi_virtmap_load(); \ + __efi_fpsimd_begin(); \ ++ spin_lock(&efi_rt_lock); \ + }) + + #undef arch_efi_call_virt +@@ -33,10 +34,12 @@ int efi_set_mapping_permissions(struct m + + #define arch_efi_call_virt_teardown() \ + ({ \ ++ spin_unlock(&efi_rt_lock); \ + __efi_fpsimd_end(); \ + efi_virtmap_unload(); \ + }) + ++extern spinlock_t efi_rt_lock; + efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); + + #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) +--- a/arch/arm64/kernel/efi-rt-wrapper.S ++++ b/arch/arm64/kernel/efi-rt-wrapper.S +@@ -16,6 +16,12 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) + */ + stp x1, x18, [sp, #16] + ++ ldr_l x16, efi_rt_stack_top ++ mov sp, x16 ++#ifdef CONFIG_SHADOW_CALL_STACK ++ str x18, [sp, #-16]! ++#endif ++ + /* + * We are lucky enough that no EFI runtime services take more than + * 5 arguments, so all are passed in registers rather than via the +@@ -29,6 +35,7 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) + mov x4, x6 + blr x8 + ++ mov sp, x29 + ldp x1, x2, [sp, #16] + cmp x2, x18 + ldp x29, x30, [sp], #32 +@@ -42,6 +49,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) + * called with preemption disabled and a separate shadow stack is used + * for interrupts. + */ +- mov x18, x2 ++#ifdef CONFIG_SHADOW_CALL_STACK ++ ldr_l x18, efi_rt_stack_top ++ ldr x18, [x18, #-16] ++#endif ++ + b efi_handle_corrupted_x18 // tail call + SYM_FUNC_END(__efi_rt_asm_wrapper) +--- a/arch/arm64/kernel/efi.c ++++ b/arch/arm64/kernel/efi.c +@@ -144,3 +144,30 @@ asmlinkage efi_status_t efi_handle_corru + pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f); + return s; + } ++ ++DEFINE_SPINLOCK(efi_rt_lock); ++ ++asmlinkage u64 *efi_rt_stack_top __ro_after_init; ++ ++/* EFI requires 8 KiB of stack space for runtime services */ ++static_assert(THREAD_SIZE >= SZ_8K); ++ ++static int __init arm64_efi_rt_init(void) ++{ ++ void *p; ++ ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) ++ return 0; ++ ++ p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL, ++ NUMA_NO_NODE, &&l); ++l: if (!p) { ++ pr_warn("Failed to allocate EFI runtime stack\n"); ++ clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); ++ return -ENOMEM; ++ } ++ ++ efi_rt_stack_top = p + THREAD_SIZE; ++ return 0; ++} ++core_initcall(arm64_efi_rt_init); diff --git a/queue-6.1/cifs-reduce-roundtrips-on-create-qinfo-requests.patch b/queue-6.1/cifs-reduce-roundtrips-on-create-qinfo-requests.patch new file mode 100644 index 00000000000..d2f5df57d4b --- /dev/null +++ b/queue-6.1/cifs-reduce-roundtrips-on-create-qinfo-requests.patch @@ -0,0 +1,256 @@ +From c877ce47e1378dbafa6f1bf84c0c83a05ca8972a Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 12 Dec 2022 23:39:37 -0300 +Subject: cifs: reduce roundtrips on create/qinfo requests + +From: Paulo Alcantara + +commit c877ce47e1378dbafa6f1bf84c0c83a05ca8972a upstream. + +To work around some Window servers that return +STATUS_OBJECT_NAME_INVALID on query infos under DFS namespaces that +contain non-ASCII characters, we started checking for -ENOENT on every +file open, and if so, then send additional requests to figure out +whether it is a DFS link or not. It means that all those requests +will be sent to every non-existing file. + +So, in order to reduce the number of roundtrips, check earlier whether +status code is STATUS_OBJECT_NAME_INVALID and tcon supports dfs, and +if so, then map -ENOENT to -EREMOTE so mount or automount will take +care of chasing the DFS link -- if it isn't an DFS link, then -ENOENT +will be returned appropriately. + +Before patch + + SMB2 438 Create Request File: ada.test\dfs\foo;GetInfo Request... + SMB2 310 Create Response, Error: STATUS_OBJECT_NAME_NOT_FOUND;... + SMB2 228 Ioctl Request FSCTL_DFS_GET_REFERRALS, File: \ada.test\dfs\foo + SMB2 143 Ioctl Response, Error: STATUS_OBJECT_PATH_NOT_FOUND + SMB2 438 Create Request File: ada.test\dfs\foo;GetInfo Request... + SMB2 310 Create Response, Error: STATUS_OBJECT_NAME_NOT_FOUND;... + SMB2 228 Ioctl Request FSCTL_DFS_GET_REFERRALS, File: \ada.test\dfs\foo + SMB2 143 Ioctl Response, Error: STATUS_OBJECT_PATH_NOT_FOUND + +After patch + + SMB2 438 Create Request File: ada.test\dfs\foo;GetInfo Request... + SMB2 310 Create Response, Error: STATUS_OBJECT_NAME_NOT_FOUND;... + SMB2 438 Create Request File: ada.test\dfs\foo;GetInfo Request... + SMB2 310 Create Response, Error: STATUS_OBJECT_NAME_NOT_FOUND;... + +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/connect.c | 16 ---------------- + fs/cifs/inode.c | 6 ------ + fs/cifs/misc.c | 45 --------------------------------------------- + fs/cifs/smb2inode.c | 45 ++++++++++++++++++++++++++++++++------------- + fs/cifs/smb2ops.c | 28 ++++++++++++++++++++++++---- + 5 files changed, 56 insertions(+), 84 deletions(-) + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -3554,9 +3554,6 @@ static int is_path_remote(struct mount_c + struct cifs_tcon *tcon = mnt_ctx->tcon; + struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; + char *full_path; +-#ifdef CONFIG_CIFS_DFS_UPCALL +- bool nodfs = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS; +-#endif + + if (!server->ops->is_path_accessible) + return -EOPNOTSUPP; +@@ -3573,19 +3570,6 @@ static int is_path_remote(struct mount_c + + rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, + full_path); +-#ifdef CONFIG_CIFS_DFS_UPCALL +- if (nodfs) { +- if (rc == -EREMOTE) +- rc = -EOPNOTSUPP; +- goto out; +- } +- +- /* path *might* exist with non-ASCII characters in DFS root +- * try again with full path (only if nodfs is not set) */ +- if (rc == -ENOENT && is_tcon_dfs(tcon)) +- rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, cifs_sb, +- full_path); +-#endif + if (rc != 0 && rc != -EREMOTE) + goto out; + +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -991,12 +991,6 @@ int cifs_get_inode_info(struct inode **i + } + rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data, + &adjust_tz, &is_reparse_point); +-#ifdef CONFIG_CIFS_DFS_UPCALL +- if (rc == -ENOENT && is_tcon_dfs(tcon)) +- rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, +- cifs_sb, +- full_path); +-#endif + data = &tmp_data; + } + +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -1314,49 +1314,4 @@ int cifs_update_super_prepath(struct cif + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + return 0; + } +- +-/** cifs_dfs_query_info_nonascii_quirk +- * Handle weird Windows SMB server behaviour. It responds with +- * STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request +- * for "\\\" DFS reference, +- * where contains non-ASCII unicode symbols. +- * +- * Check such DFS reference. +- */ +-int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid, +- struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, +- const char *linkpath) +-{ +- char *treename, *dfspath, sep; +- int treenamelen, linkpathlen, rc; +- +- treename = tcon->tree_name; +- /* MS-DFSC: All paths in REQ_GET_DFS_REFERRAL and RESP_GET_DFS_REFERRAL +- * messages MUST be encoded with exactly one leading backslash, not two +- * leading backslashes. +- */ +- sep = CIFS_DIR_SEP(cifs_sb); +- if (treename[0] == sep && treename[1] == sep) +- treename++; +- linkpathlen = strlen(linkpath); +- treenamelen = strnlen(treename, MAX_TREE_SIZE + 1); +- dfspath = kzalloc(treenamelen + linkpathlen + 1, GFP_KERNEL); +- if (!dfspath) +- return -ENOMEM; +- if (treenamelen) +- memcpy(dfspath, treename, treenamelen); +- memcpy(dfspath + treenamelen, linkpath, linkpathlen); +- rc = dfs_cache_find(xid, tcon->ses, cifs_sb->local_nls, +- cifs_remap(cifs_sb), dfspath, NULL, NULL); +- if (rc == 0) { +- cifs_dbg(FYI, "DFS ref '%s' is found, emulate -EREMOTE\n", +- dfspath); +- rc = -EREMOTE; +- } else { +- cifs_dbg(FYI, "%s: dfs_cache_find returned %d\n", __func__, rc); +- } +- kfree(dfspath); +- return rc; +-} + #endif +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -540,22 +540,41 @@ int smb2_query_path_info(const unsigned + rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, + create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile, + err_iov, err_buftype); +- if (rc == -EOPNOTSUPP) { +- if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && +- ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE && +- ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { +- rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target); ++ if (rc) { ++ struct smb2_hdr *hdr = err_iov[0].iov_base; ++ ++ if (unlikely(!hdr || err_buftype[0] == CIFS_NO_BUFFER)) ++ goto out; ++ if (rc == -EOPNOTSUPP && hdr->Command == SMB2_CREATE && ++ hdr->Status == STATUS_STOPPED_ON_SYMLINK) { ++ rc = smb2_parse_symlink_response(cifs_sb, err_iov, ++ &data->symlink_target); + if (rc) + goto out; +- } +- *reparse = true; +- create_options |= OPEN_REPARSE_POINT; + +- /* Failed on a symbolic link - query a reparse point info */ +- cifs_get_readable_path(tcon, full_path, &cfile); +- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, +- FILE_OPEN, create_options, ACL_NO_MODE, data, +- SMB2_OP_QUERY_INFO, cfile, NULL, NULL); ++ *reparse = true; ++ create_options |= OPEN_REPARSE_POINT; ++ ++ /* Failed on a symbolic link - query a reparse point info */ ++ cifs_get_readable_path(tcon, full_path, &cfile); ++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, ++ FILE_READ_ATTRIBUTES, FILE_OPEN, ++ create_options, ACL_NO_MODE, data, ++ SMB2_OP_QUERY_INFO, cfile, NULL, NULL); ++ goto out; ++ } else if (rc != -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && ++ hdr->Status == STATUS_OBJECT_NAME_INVALID) { ++ /* ++ * Handle weird Windows SMB server behaviour. It responds with ++ * STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request ++ * for "\\\" DFS reference, ++ * where contains non-ASCII unicode symbols. ++ */ ++ rc = -EREMOTE; ++ } ++ if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && cifs_sb && ++ (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)) ++ rc = -EOPNOTSUPP; + } + + out: +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -797,7 +797,9 @@ smb2_is_path_accessible(const unsigned i + int rc; + __le16 *utf16_path; + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; ++ int err_buftype = CIFS_NO_BUFFER; + struct cifs_open_parms oparms; ++ struct kvec err_iov = {}; + struct cifs_fid fid; + struct cached_fid *cfid; + +@@ -821,14 +823,32 @@ smb2_is_path_accessible(const unsigned i + oparms.fid = &fid; + oparms.reconnect = false; + +- rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL, +- NULL); ++ rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, ++ &err_iov, &err_buftype); + if (rc) { +- kfree(utf16_path); +- return rc; ++ struct smb2_hdr *hdr = err_iov.iov_base; ++ ++ if (unlikely(!hdr || err_buftype == CIFS_NO_BUFFER)) ++ goto out; ++ /* ++ * Handle weird Windows SMB server behaviour. It responds with ++ * STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request ++ * for "\\\" DFS reference, ++ * where contains non-ASCII unicode symbols. ++ */ ++ if (rc != -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && ++ hdr->Status == STATUS_OBJECT_NAME_INVALID) ++ rc = -EREMOTE; ++ if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && cifs_sb && ++ (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)) ++ rc = -EOPNOTSUPP; ++ goto out; + } + + rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); ++ ++out: ++ free_rsp_buf(err_buftype, err_iov.iov_base); + kfree(utf16_path); + return rc; + } diff --git a/queue-6.1/efi-rt-wrapper-add-missing-include.patch b/queue-6.1/efi-rt-wrapper-add-missing-include.patch new file mode 100644 index 00000000000..6a34c72167d --- /dev/null +++ b/queue-6.1/efi-rt-wrapper-add-missing-include.patch @@ -0,0 +1,30 @@ +From 18bba1843fc7f264f58c9345d00827d082f9c558 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Mon, 9 Jan 2023 12:41:46 +0100 +Subject: efi: rt-wrapper: Add missing include + +From: Ard Biesheuvel + +commit 18bba1843fc7f264f58c9345d00827d082f9c558 upstream. + +Add the missing #include of asm/assembler.h, which is where the ldr_l +macro is defined. + +Fixes: ff7a167961d1b97e ("arm64: efi: Execute runtime services from a dedicated stack") +Signed-off-by: Ard Biesheuvel +Cc: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/efi-rt-wrapper.S | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/kernel/efi-rt-wrapper.S ++++ b/arch/arm64/kernel/efi-rt-wrapper.S +@@ -4,6 +4,7 @@ + */ + + #include ++#include + + SYM_FUNC_START(__efi_rt_asm_wrapper) + stp x29, x30, [sp, #-32]! diff --git a/queue-6.1/fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch b/queue-6.1/fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch new file mode 100644 index 00000000000..a883cbee862 --- /dev/null +++ b/queue-6.1/fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch @@ -0,0 +1,36 @@ +From 6d5c9e79b726cc473d40e9cb60976dbe8e669624 Mon Sep 17 00:00:00 2001 +From: Alon Zahavi +Date: Mon, 15 Aug 2022 14:07:12 +0300 +Subject: fs/ntfs3: Fix attr_punch_hole() null pointer derenference + +From: Alon Zahavi + +commit 6d5c9e79b726cc473d40e9cb60976dbe8e669624 upstream. + +The bug occours due to a misuse of `attr` variable instead of `attr_b`. +`attr` is being initialized as NULL, then being derenfernced +as `attr->res.data_size`. + +This bug causes a crash of the ntfs3 driver itself, +If compiled directly to the kernel, it crashes the whole system. + +Signed-off-by: Alon Zahavi +Co-developed-by: Tal Lossos +Signed-off-by: Tal Lossos +Signed-off-by: Konstantin Komarov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ntfs3/attrib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -2038,7 +2038,7 @@ int attr_punch_hole(struct ntfs_inode *n + return -ENOENT; + + if (!attr_b->non_res) { +- u32 data_size = le32_to_cpu(attr->res.data_size); ++ u32 data_size = le32_to_cpu(attr_b->res.data_size); + u32 from, to; + + if (vbo > data_size) diff --git a/queue-6.1/series b/queue-6.1/series index af02e9e404b..8f6258d5056 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -142,3 +142,7 @@ drm-amd-display-calculate-output_color_space-after-pixel-encoding-adjustment.pat drm-amd-display-fix-color_space_ycbcr2020_type-matrix.patch drm-amd-display-disable-s-g-display-on-dcn-3.1.5.patch drm-amd-display-disable-s-g-display-on-dcn-3.1.4.patch +cifs-reduce-roundtrips-on-create-qinfo-requests.patch +fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch +arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch +efi-rt-wrapper-add-missing-include.patch