From: Greg Kroah-Hartman Date: Fri, 17 Dec 2021 15:09:05 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v4.4.296~58 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=713106befa42785c588bcd223bd6ff24a1824838;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: arm64-dts-ten64-remove-redundant-interrupt-declaration-for-gpio-keys.patch audit-improve-robustness-of-the-audit-queue-handling.patch bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch bpf-fix-kernel-address-leakage-in-atomic-fetch.patch bpf-fix-signed-bounds-propagation-after-mov32.patch bpf-make-32-64-bounds-propagation-slightly-more-robust.patch bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch btrfs-convert-latest_bdev-type-to-btrfs_device-and-rename.patch btrfs-remove-stale-comment-about-the-btrfs_show_devname.patch btrfs-update-latest_dev-when-we-create-a-sprout-device.patch btrfs-use-latest_dev-in-btrfs_show_devname.patch ceph-fix-up-non-directory-creation-in-sgid-directories.patch dm-btree-remove-fix-use-after-free-in-rebalance_children.patch drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdmi_to_i915.patch drm-i915-hdmi-turn-dp-tmds-output-buffers-back-on-in-encoder-shutdown.patch pinctrl-amd-fix-wakeups-when-irq-is-shared-with-sci.patch recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch s390-entry-fix-duplicate-tracking-of-irq-nesting-level.patch scsi-ufs-core-retry-start_stop-on-unit_attention.patch vdpa-check-that-offsets-are-within-bounds.patch vduse-check-that-offset-is-within-bounds-in-get_config.patch vduse-fix-memory-corruption-in-vduse_dev_ioctl.patch virtio_ring-fix-querying-of-maximum-dma-mapping-size-for-virtio-device.patch --- diff --git a/queue-5.15/arm64-dts-ten64-remove-redundant-interrupt-declaration-for-gpio-keys.patch b/queue-5.15/arm64-dts-ten64-remove-redundant-interrupt-declaration-for-gpio-keys.patch new file mode 100644 index 00000000000..3ed976809a6 --- /dev/null +++ b/queue-5.15/arm64-dts-ten64-remove-redundant-interrupt-declaration-for-gpio-keys.patch @@ -0,0 +1,41 @@ +From c88c5e461939a06ae769a01649d5c6b5a156f883 Mon Sep 17 00:00:00 2001 +From: Mathew McBride +Date: Mon, 22 Nov 2021 02:55:54 +0000 +Subject: arm64: dts: ten64: remove redundant interrupt declaration for gpio-keys + +From: Mathew McBride + +commit c88c5e461939a06ae769a01649d5c6b5a156f883 upstream. + +gpio-keys already 'inherits' the interrupts from the controller +of the specified GPIO, so having another declaration is redundant. +On >=v5.15 this started causing an oops under gpio_keys_probe as +the IRQ was already claimed. + +Signed-off-by: Mathew McBride +Fixes: 418962eea358 ("arm64: dts: add device tree for Traverse Ten64 (LS1088A)") +Cc: stable@vger.kernel.org +Signed-off-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts +@@ -38,7 +38,6 @@ + powerdn { + label = "External Power Down"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; +- interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>; + linux,code = ; + }; + +@@ -46,7 +45,6 @@ + admin { + label = "ADMIN button"; + gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>; +- interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>; + linux,code = ; + }; + }; diff --git a/queue-5.15/audit-improve-robustness-of-the-audit-queue-handling.patch b/queue-5.15/audit-improve-robustness-of-the-audit-queue-handling.patch new file mode 100644 index 00000000000..7901c45fa2e --- /dev/null +++ b/queue-5.15/audit-improve-robustness-of-the-audit-queue-handling.patch @@ -0,0 +1,109 @@ +From f4b3ee3c85551d2d343a3ba159304066523f730f Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Thu, 9 Dec 2021 11:46:07 -0500 +Subject: audit: improve robustness of the audit queue handling + +From: Paul Moore + +commit f4b3ee3c85551d2d343a3ba159304066523f730f upstream. + +If the audit daemon were ever to get stuck in a stopped state the +kernel's kauditd_thread() could get blocked attempting to send audit +records to the userspace audit daemon. With the kernel thread +blocked it is possible that the audit queue could grow unbounded as +certain audit record generating events must be exempt from the queue +limits else the system enter a deadlock state. + +This patch resolves this problem by lowering the kernel thread's +socket sending timeout from MAX_SCHEDULE_TIMEOUT to HZ/10 and tweaks +the kauditd_send_queue() function to better manage the various audit +queues when connection problems occur between the kernel and the +audit daemon. With this patch, the backlog may temporarily grow +beyond the defined limits when the audit daemon is stopped and the +system is under heavy audit pressure, but kauditd_thread() will +continue to make progress and drain the queues as it would for other +connection problems. For example, with the audit daemon put into a +stopped state and the system configured to audit every syscall it +was still possible to shutdown the system without a kernel panic, +deadlock, etc.; granted, the system was slow to shutdown but that is +to be expected given the extreme pressure of recording every syscall. + +The timeout value of HZ/10 was chosen primarily through +experimentation and this developer's "gut feeling". There is likely +no one perfect value, but as this scenario is limited in scope (root +privileges would be needed to send SIGSTOP to the audit daemon), it +is likely not worth exposing this as a tunable at present. This can +always be done at a later date if it proves necessary. + +Cc: stable@vger.kernel.org +Fixes: 5b52330bbfe63 ("audit: fix auditd/kernel connection state tracking") +Reported-by: Gaosheng Cui +Tested-by: Gaosheng Cui +Reviewed-by: Richard Guy Briggs +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + kernel/audit.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -718,7 +718,7 @@ static int kauditd_send_queue(struct soc + { + int rc = 0; + struct sk_buff *skb; +- static unsigned int failed = 0; ++ unsigned int failed = 0; + + /* NOTE: kauditd_thread takes care of all our locking, we just use + * the netlink info passed to us (e.g. sk and portid) */ +@@ -735,32 +735,30 @@ static int kauditd_send_queue(struct soc + continue; + } + ++retry: + /* grab an extra skb reference in case of error */ + skb_get(skb); + rc = netlink_unicast(sk, skb, portid, 0); + if (rc < 0) { +- /* fatal failure for our queue flush attempt? */ ++ /* send failed - try a few times unless fatal error */ + if (++failed >= retry_limit || + rc == -ECONNREFUSED || rc == -EPERM) { +- /* yes - error processing for the queue */ + sk = NULL; + if (err_hook) + (*err_hook)(skb); +- if (!skb_hook) +- goto out; +- /* keep processing with the skb_hook */ ++ if (rc == -EAGAIN) ++ rc = 0; ++ /* continue to drain the queue */ + continue; + } else +- /* no - requeue to preserve ordering */ +- skb_queue_head(queue, skb); ++ goto retry; + } else { +- /* it worked - drop the extra reference and continue */ ++ /* skb sent - drop the extra reference and continue */ + consume_skb(skb); + failed = 0; + } + } + +-out: + return (rc >= 0 ? 0 : rc); + } + +@@ -1609,7 +1607,8 @@ static int __net_init audit_net_init(str + audit_panic("cannot initialize netlink socket in namespace"); + return -ENOMEM; + } +- aunet->sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; ++ /* limit the timeout in case auditd is blocked/stopped */ ++ aunet->sk->sk_sndtimeo = HZ / 10; + + return 0; + } diff --git a/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch b/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch new file mode 100644 index 00000000000..aad743511bf --- /dev/null +++ b/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch @@ -0,0 +1,59 @@ +From a82fe085f344ef20b452cd5f481010ff96b5c4cd Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Tue, 7 Dec 2021 11:02:02 +0000 +Subject: bpf: Fix kernel address leakage in atomic cmpxchg's r0 aux reg + +From: Daniel Borkmann + +commit a82fe085f344ef20b452cd5f481010ff96b5c4cd upstream. + +The implementation of BPF_CMPXCHG on a high level has the following parameters: + + .-[old-val] .-[new-val] + BPF_R0 = cmpxchg{32,64}(DST_REG + insn->off, BPF_R0, SRC_REG) + `-[mem-loc] `-[old-val] + +Given a BPF insn can only have two registers (dst, src), the R0 is fixed and +used as an auxilliary register for input (old value) as well as output (returning +old value from memory location). While the verifier performs a number of safety +checks, it misses to reject unprivileged programs where R0 contains a pointer as +old value. + +Through brute-forcing it takes about ~16sec on my machine to leak a kernel pointer +with BPF_CMPXCHG. The PoC is basically probing for kernel addresses by storing the +guessed address into the map slot as a scalar, and using the map value pointer as +R0 while SRC_REG has a canary value to detect a matching address. + +Fix it by checking R0 for pointers, and reject if that's the case for unprivileged +programs. + +Fixes: 5ffa25502b5a ("bpf: Add instructions for atomic_[cmp]xchg") +Reported-by: Ryota Shiga (Flatt Security) +Acked-by: Brendan Jackman +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -4386,9 +4386,16 @@ static int check_atomic(struct bpf_verif + + if (insn->imm == BPF_CMPXCHG) { + /* Check comparison of R0 with memory location */ +- err = check_reg_arg(env, BPF_REG_0, SRC_OP); ++ const u32 aux_reg = BPF_REG_0; ++ ++ err = check_reg_arg(env, aux_reg, SRC_OP); + if (err) + return err; ++ ++ if (is_pointer_value(env, aux_reg)) { ++ verbose(env, "R%d leaks addr into mem\n", aux_reg); ++ return -EACCES; ++ } + } + + if (is_pointer_value(env, insn->src_reg)) { diff --git a/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-fetch.patch b/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-fetch.patch new file mode 100644 index 00000000000..d8035a87f6d --- /dev/null +++ b/queue-5.15/bpf-fix-kernel-address-leakage-in-atomic-fetch.patch @@ -0,0 +1,69 @@ +From 7d3baf0afa3aa9102d6a521a8e4c41888bb79882 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Tue, 7 Dec 2021 12:51:56 +0000 +Subject: bpf: Fix kernel address leakage in atomic fetch + +From: Daniel Borkmann + +commit 7d3baf0afa3aa9102d6a521a8e4c41888bb79882 upstream. + +The change in commit 37086bfdc737 ("bpf: Propagate stack bounds to registers +in atomics w/ BPF_FETCH") around check_mem_access() handling is buggy since +this would allow for unprivileged users to leak kernel pointers. For example, +an atomic fetch/and with -1 on a stack destination which holds a spilled +pointer will migrate the spilled register type into a scalar, which can then +be exported out of the program (since scalar != pointer) by dumping it into +a map value. + +The original implementation of XADD was preventing this situation by using +a double call to check_mem_access() one with BPF_READ and a subsequent one +with BPF_WRITE, in both cases passing -1 as a placeholder value instead of +register as per XADD semantics since it didn't contain a value fetch. The +BPF_READ also included a check in check_stack_read_fixed_off() which rejects +the program if the stack slot is of __is_pointer_value() if dst_regno < 0. +The latter is to distinguish whether we're dealing with a regular stack spill/ +fill or some arithmetical operation which is disallowed on non-scalars, see +also 6e7e63cbb023 ("bpf: Forbid XADD on spilled pointers for unprivileged +users") for more context on check_mem_access() and its handling of placeholder +value -1. + +One minimally intrusive option to fix the leak is for the BPF_FETCH case to +initially check the BPF_READ case via check_mem_access() with -1 as register, +followed by the actual load case with non-negative load_reg to propagate +stack bounds to registers. + +Fixes: 37086bfdc737 ("bpf: Propagate stack bounds to registers in atomics w/ BPF_FETCH") +Reported-by: +Acked-by: Brendan Jackman +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -4417,13 +4417,19 @@ static int check_atomic(struct bpf_verif + load_reg = -1; + } + +- /* check whether we can read the memory */ ++ /* Check whether we can read the memory, with second call for fetch ++ * case to simulate the register fill. ++ */ + err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, +- BPF_SIZE(insn->code), BPF_READ, load_reg, true); ++ BPF_SIZE(insn->code), BPF_READ, -1, true); ++ if (!err && load_reg >= 0) ++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, ++ BPF_SIZE(insn->code), BPF_READ, load_reg, ++ true); + if (err) + return err; + +- /* check whether we can write into the same memory */ ++ /* Check whether we can write into the same memory. */ + err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_WRITE, -1, true); + if (err) diff --git a/queue-5.15/bpf-fix-signed-bounds-propagation-after-mov32.patch b/queue-5.15/bpf-fix-signed-bounds-propagation-after-mov32.patch new file mode 100644 index 00000000000..f86318606c6 --- /dev/null +++ b/queue-5.15/bpf-fix-signed-bounds-propagation-after-mov32.patch @@ -0,0 +1,97 @@ +From 3cf2b61eb06765e27fec6799292d9fb46d0b7e60 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 15 Dec 2021 22:02:19 +0000 +Subject: bpf: Fix signed bounds propagation after mov32 + +From: Daniel Borkmann + +commit 3cf2b61eb06765e27fec6799292d9fb46d0b7e60 upstream. + +For the case where both s32_{min,max}_value bounds are positive, the +__reg_assign_32_into_64() directly propagates them to their 64 bit +counterparts, otherwise it pessimises them into [0,u32_max] universe and +tries to refine them later on by learning through the tnum as per comment +in mentioned function. However, that does not always happen, for example, +in mov32 operation we call zext_32_to_64(dst_reg) which invokes the +__reg_assign_32_into_64() as is without subsequent bounds update as +elsewhere thus no refinement based on tnum takes place. + +Thus, not calling into the __update_reg_bounds() / __reg_deduce_bounds() / +__reg_bound_offset() triplet as we do, for example, in case of ALU ops via +adjust_scalar_min_max_vals(), will lead to more pessimistic bounds when +dumping the full register state: + +Before fix: + + 0: (b4) w0 = -1 + 1: R0_w=invP4294967295 + (id=0,imm=ffffffff, + smin_value=4294967295,smax_value=4294967295, + umin_value=4294967295,umax_value=4294967295, + var_off=(0xffffffff; 0x0), + s32_min_value=-1,s32_max_value=-1, + u32_min_value=-1,u32_max_value=-1) + + 1: (bc) w0 = w0 + 2: R0_w=invP4294967295 + (id=0,imm=ffffffff, + smin_value=0,smax_value=4294967295, + umin_value=4294967295,umax_value=4294967295, + var_off=(0xffffffff; 0x0), + s32_min_value=-1,s32_max_value=-1, + u32_min_value=-1,u32_max_value=-1) + +Technically, the smin_value=0 and smax_value=4294967295 bounds are not +incorrect, but given the register is still a constant, they break assumptions +about const scalars that smin_value == smax_value and umin_value == umax_value. + +After fix: + + 0: (b4) w0 = -1 + 1: R0_w=invP4294967295 + (id=0,imm=ffffffff, + smin_value=4294967295,smax_value=4294967295, + umin_value=4294967295,umax_value=4294967295, + var_off=(0xffffffff; 0x0), + s32_min_value=-1,s32_max_value=-1, + u32_min_value=-1,u32_max_value=-1) + + 1: (bc) w0 = w0 + 2: R0_w=invP4294967295 + (id=0,imm=ffffffff, + smin_value=4294967295,smax_value=4294967295, + umin_value=4294967295,umax_value=4294967295, + var_off=(0xffffffff; 0x0), + s32_min_value=-1,s32_max_value=-1, + u32_min_value=-1,u32_max_value=-1) + +Without the smin_value == smax_value and umin_value == umax_value invariant +being intact for const scalars, it is possible to leak out kernel pointers +from unprivileged user space if the latter is enabled. For example, when such +registers are involved in pointer arithmtics, then adjust_ptr_min_max_vals() +will taint the destination register into an unknown scalar, and the latter +can be exported and stored e.g. into a BPF map value. + +Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking") +Reported-by: Kuee K1r0a +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Acked-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -8120,6 +8120,10 @@ static int check_alu_op(struct bpf_verif + insn->dst_reg); + } + zext_32_to_64(dst_reg); ++ ++ __update_reg_bounds(dst_reg); ++ __reg_deduce_bounds(dst_reg); ++ __reg_bound_offset(dst_reg); + } + } else { + /* case: R = imm diff --git a/queue-5.15/bpf-make-32-64-bounds-propagation-slightly-more-robust.patch b/queue-5.15/bpf-make-32-64-bounds-propagation-slightly-more-robust.patch new file mode 100644 index 00000000000..6eb5c51fa37 --- /dev/null +++ b/queue-5.15/bpf-make-32-64-bounds-propagation-slightly-more-robust.patch @@ -0,0 +1,62 @@ +From e572ff80f05c33cd0cb4860f864f5c9c044280b6 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 15 Dec 2021 22:28:48 +0000 +Subject: bpf: Make 32->64 bounds propagation slightly more robust + +From: Daniel Borkmann + +commit e572ff80f05c33cd0cb4860f864f5c9c044280b6 upstream. + +Make the bounds propagation in __reg_assign_32_into_64() slightly more +robust and readable by aligning it similarly as we did back in the +__reg_combine_64_into_32() counterpart. Meaning, only propagate or +pessimize them as a smin/smax pair. + +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Acked-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1358,22 +1358,28 @@ static void __reg_bound_offset(struct bp + reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off); + } + ++static bool __reg32_bound_s64(s32 a) ++{ ++ return a >= 0 && a <= S32_MAX; ++} ++ + static void __reg_assign_32_into_64(struct bpf_reg_state *reg) + { + reg->umin_value = reg->u32_min_value; + reg->umax_value = reg->u32_max_value; +- /* Attempt to pull 32-bit signed bounds into 64-bit bounds +- * but must be positive otherwise set to worse case bounds +- * and refine later from tnum. ++ ++ /* Attempt to pull 32-bit signed bounds into 64-bit bounds but must ++ * be positive otherwise set to worse case bounds and refine later ++ * from tnum. + */ +- if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0) +- reg->smax_value = reg->s32_max_value; +- else +- reg->smax_value = U32_MAX; +- if (reg->s32_min_value >= 0) ++ if (__reg32_bound_s64(reg->s32_min_value) && ++ __reg32_bound_s64(reg->s32_max_value)) { + reg->smin_value = reg->s32_min_value; +- else ++ reg->smax_value = reg->s32_max_value; ++ } else { + reg->smin_value = 0; ++ reg->smax_value = U32_MAX; ++ } + } + + static void __reg_combine_32_into_64(struct bpf_reg_state *reg) diff --git a/queue-5.15/bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch b/queue-5.15/bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch new file mode 100644 index 00000000000..0ec7f337df2 --- /dev/null +++ b/queue-5.15/bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch @@ -0,0 +1,82 @@ +From 180486b430f4e22cc00a478163d942804baae4b5 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Tue, 7 Dec 2021 10:07:04 +0000 +Subject: bpf, selftests: Add test case for atomic fetch on spilled pointer + +From: Daniel Borkmann + +commit 180486b430f4e22cc00a478163d942804baae4b5 upstream. + +Test whether unprivileged would be able to leak the spilled pointer either +by exporting the returned value from the atomic{32,64} operation or by reading +and exporting the value from the stack after the atomic operation took place. + +Note that for unprivileged, the below atomic cmpxchg test case named "Dest +pointer in r0 - succeed" is failing. The reason is that in the dst memory +location (r10 -8) there is the spilled register r10: + + 0: R1=ctx(id=0,off=0,imm=0) R10=fp0 + 0: (bf) r0 = r10 + 1: R0_w=fp0 R1=ctx(id=0,off=0,imm=0) R10=fp0 + 1: (7b) *(u64 *)(r10 -8) = r0 + 2: R0_w=fp0 R1=ctx(id=0,off=0,imm=0) R10=fp0 fp-8_w=fp + 2: (b7) r1 = 0 + 3: R0_w=fp0 R1_w=invP0 R10=fp0 fp-8_w=fp + 3: (db) r0 = atomic64_cmpxchg((u64 *)(r10 -8), r0, r1) + 4: R0_w=fp0 R1_w=invP0 R10=fp0 fp-8_w=mmmmmmmm + 4: (79) r1 = *(u64 *)(r0 -8) + 5: R0_w=fp0 R1_w=invP(id=0) R10=fp0 fp-8_w=mmmmmmmm + 5: (b7) r0 = 0 + 6: R0_w=invP0 R1_w=invP(id=0) R10=fp0 fp-8_w=mmmmmmmm + 6: (95) exit + +However, allowing this case for unprivileged is a bit useless given an +update with a new pointer will fail anyway: + + 0: R1=ctx(id=0,off=0,imm=0) R10=fp0 + 0: (bf) r0 = r10 + 1: R0_w=fp0 R1=ctx(id=0,off=0,imm=0) R10=fp0 + 1: (7b) *(u64 *)(r10 -8) = r0 + 2: R0_w=fp0 R1=ctx(id=0,off=0,imm=0) R10=fp0 fp-8_w=fp + 2: (db) r0 = atomic64_cmpxchg((u64 *)(r10 -8), r0, r10) + R10 leaks addr into mem + +Acked-by: Brendan Jackman +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +[only backport one test for 5.15.y - gregkh] +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c | 23 ++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c ++++ b/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c +@@ -118,4 +118,27 @@ + BPF_EXIT_INSN(), + }, + .result = ACCEPT, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "leaking pointer from stack off -8", ++}, ++{ ++ "Dest pointer in r0 - succeed, check 2", ++ .insns = { ++ /* r0 = &val */ ++ BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), ++ /* val = r0; */ ++ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), ++ /* r5 = &val */ ++ BPF_MOV64_REG(BPF_REG_5, BPF_REG_10), ++ /* r0 = atomic_cmpxchg(&val, r0, r5); */ ++ BPF_ATOMIC_OP(BPF_DW, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8), ++ /* r1 = *r0 */ ++ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), ++ /* exit(0); */ ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = ACCEPT, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R5 leaks addr into mem", + }, diff --git a/queue-5.15/bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch b/queue-5.15/bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch new file mode 100644 index 00000000000..2122bb2ff54 --- /dev/null +++ b/queue-5.15/bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch @@ -0,0 +1,74 @@ +From b1a7288dedc6caf9023f2676b4f5ed34cf0d4029 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 15 Dec 2021 23:48:54 +0000 +Subject: bpf, selftests: Add test case trying to taint map value pointer + +From: Daniel Borkmann + +commit b1a7288dedc6caf9023f2676b4f5ed34cf0d4029 upstream. + +Add a test case which tries to taint map value pointer arithmetic into a +unknown scalar with subsequent export through the map. + +Before fix: + + # ./test_verifier 1186 + #1186/u map access: trying to leak tained dst reg FAIL + Unexpected success to load! + verification time 24 usec + stack depth 8 + processed 15 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1 + #1186/p map access: trying to leak tained dst reg FAIL + Unexpected success to load! + verification time 8 usec + stack depth 8 + processed 15 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1 + Summary: 0 PASSED, 0 SKIPPED, 2 FAILED + +After fix: + + # ./test_verifier 1186 + #1186/u map access: trying to leak tained dst reg OK + #1186/p map access: trying to leak tained dst reg OK + Summary: 2 PASSED, 0 SKIPPED, 0 FAILED + +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Acked-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/value_ptr_arith.c | 23 +++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c ++++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +@@ -1078,6 +1078,29 @@ + .errstr_unpriv = "R0 pointer -= pointer prohibited", + }, + { ++ "map access: trying to leak tained dst reg", ++ .insns = { ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), ++ BPF_LD_MAP_FD(BPF_REG_1, 0), ++ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), ++ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), ++ BPF_EXIT_INSN(), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), ++ BPF_MOV32_IMM(BPF_REG_1, 0xFFFFFFFF), ++ BPF_MOV32_REG(BPF_REG_1, BPF_REG_1), ++ BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_1), ++ BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map_array_48b = { 4 }, ++ .result = REJECT, ++ .errstr = "math between map_value pointer and 4294967295 is not allowed", ++}, ++{ + "32bit pkt_ptr -= scalar", + .insns = { + BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1, diff --git a/queue-5.15/bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch b/queue-5.15/bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch new file mode 100644 index 00000000000..5d85aee47d7 --- /dev/null +++ b/queue-5.15/bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch @@ -0,0 +1,120 @@ +From e523102cb719cbad1673b6aa2a4d5c1fa6f13799 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Mon, 13 Dec 2021 22:25:23 +0000 +Subject: bpf, selftests: Update test case for atomic cmpxchg on r0 with pointer + +From: Daniel Borkmann + +commit e523102cb719cbad1673b6aa2a4d5c1fa6f13799 upstream. + +Fix up unprivileged test case results for 'Dest pointer in r0' verifier tests +given they now need to reject R0 containing a pointer value, and add a couple +of new related ones with 32bit cmpxchg as well. + + root@foo:~/bpf/tools/testing/selftests/bpf# ./test_verifier + #0/u invalid and of negative number OK + #0/p invalid and of negative number OK + [...] + #1268/p XDP pkt read, pkt_meta' <= pkt_data, bad access 1 OK + #1269/p XDP pkt read, pkt_meta' <= pkt_data, bad access 2 OK + #1270/p XDP pkt read, pkt_data <= pkt_meta', good access OK + #1271/p XDP pkt read, pkt_data <= pkt_meta', bad access 1 OK + #1272/p XDP pkt read, pkt_data <= pkt_meta', bad access 2 OK + Summary: 1900 PASSED, 0 SKIPPED, 0 FAILED + +Acked-by: Brendan Jackman +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c | 67 +++++++++++++++++- + 1 file changed, 65 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c ++++ b/tools/testing/selftests/bpf/verifier/atomic_cmpxchg.c +@@ -71,6 +71,8 @@ + BPF_EXIT_INSN(), + }, + .result = ACCEPT, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R0 leaks addr into mem", + }, + { + "Can't use cmpxchg on uninit src reg", +@@ -119,7 +121,7 @@ + }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "leaking pointer from stack off -8", ++ .errstr_unpriv = "R0 leaks addr into mem", + }, + { + "Dest pointer in r0 - succeed, check 2", +@@ -140,5 +142,66 @@ + }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R5 leaks addr into mem", ++ .errstr_unpriv = "R0 leaks addr into mem", ++}, ++{ ++ "Dest pointer in r0 - succeed, check 3", ++ .insns = { ++ /* r0 = &val */ ++ BPF_MOV64_REG(BPF_REG_0, BPF_REG_10), ++ /* val = r0; */ ++ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), ++ /* r5 = &val */ ++ BPF_MOV64_REG(BPF_REG_5, BPF_REG_10), ++ /* r0 = atomic_cmpxchg(&val, r0, r5); */ ++ BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8), ++ /* exit(0); */ ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = REJECT, ++ .errstr = "invalid size of register fill", ++ .errstr_unpriv = "R0 leaks addr into mem", ++}, ++{ ++ "Dest pointer in r0 - succeed, check 4", ++ .insns = { ++ /* r0 = &val */ ++ BPF_MOV32_REG(BPF_REG_0, BPF_REG_10), ++ /* val = r0; */ ++ BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8), ++ /* r5 = &val */ ++ BPF_MOV32_REG(BPF_REG_5, BPF_REG_10), ++ /* r0 = atomic_cmpxchg(&val, r0, r5); */ ++ BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8), ++ /* r1 = *r10 */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -8), ++ /* exit(0); */ ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = ACCEPT, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R10 partial copy of pointer", ++}, ++{ ++ "Dest pointer in r0 - succeed, check 5", ++ .insns = { ++ /* r0 = &val */ ++ BPF_MOV32_REG(BPF_REG_0, BPF_REG_10), ++ /* val = r0; */ ++ BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8), ++ /* r5 = &val */ ++ BPF_MOV32_REG(BPF_REG_5, BPF_REG_10), ++ /* r0 = atomic_cmpxchg(&val, r0, r5); */ ++ BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8), ++ /* r1 = *r0 */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -8), ++ /* exit(0); */ ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = REJECT, ++ .errstr = "R0 invalid mem access", ++ .errstr_unpriv = "R10 partial copy of pointer", + }, diff --git a/queue-5.15/btrfs-convert-latest_bdev-type-to-btrfs_device-and-rename.patch b/queue-5.15/btrfs-convert-latest_bdev-type-to-btrfs_device-and-rename.patch new file mode 100644 index 00000000000..77ea407f986 --- /dev/null +++ b/queue-5.15/btrfs-convert-latest_bdev-type-to-btrfs_device-and-rename.patch @@ -0,0 +1,147 @@ +From foo@baz Fri Dec 17 03:55:51 PM CET 2021 +From: Anand Jain +Date: Thu, 16 Dec 2021 21:04:10 +0800 +Subject: btrfs: convert latest_bdev type to btrfs_device and rename +To: linux-kernel@vger.kernel.org, stable@vger.kernel.org +Cc: linux-btrfs@vger.kernel.org, Anand Jain , Su Yue , David Sterba +Message-ID: + +From: Anand Jain + +Commit d24fa5c1da08026be9959baca309fa0adf8708bf upstream. + +In preparation to fix a bug in btrfs_show_devname(). + +Convert fs_devices::latest_bdev type from struct block_device to struct +btrfs_device and, rename the member to fs_devices::latest_dev. +So that btrfs_show_devname() can use fs_devices::latest_dev::name. + +Tested-by: Su Yue +Signed-off-by: Anand Jain +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/disk-io.c | 6 +++--- + fs/btrfs/extent_io.c | 2 +- + fs/btrfs/inode.c | 2 +- + fs/btrfs/super.c | 2 +- + fs/btrfs/volumes.c | 10 +++++----- + fs/btrfs/volumes.h | 6 +++++- + 6 files changed, 16 insertions(+), 12 deletions(-) + +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -3229,12 +3229,12 @@ int __cold open_ctree(struct super_block + mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); + btrfs_init_btree_inode(fs_info); + +- invalidate_bdev(fs_devices->latest_bdev); ++ invalidate_bdev(fs_devices->latest_dev->bdev); + + /* + * Read super block and check the signature bytes only + */ +- disk_super = btrfs_read_dev_super(fs_devices->latest_bdev); ++ disk_super = btrfs_read_dev_super(fs_devices->latest_dev->bdev); + if (IS_ERR(disk_super)) { + err = PTR_ERR(disk_super); + goto fail_alloc; +@@ -3466,7 +3466,7 @@ int __cold open_ctree(struct super_block + * below in btrfs_init_dev_replace(). + */ + btrfs_free_extra_devids(fs_devices); +- if (!fs_devices->latest_bdev) { ++ if (!fs_devices->latest_dev->bdev) { + btrfs_err(fs_info, "failed to read devices"); + goto fail_tree_roots; + } +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -3327,7 +3327,7 @@ static int alloc_new_bio(struct btrfs_in + if (wbc) { + struct block_device *bdev; + +- bdev = fs_info->fs_devices->latest_bdev; ++ bdev = fs_info->fs_devices->latest_dev->bdev; + bio_set_dev(bio, bdev); + wbc_init_bio(wbc, bio); + } +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7967,7 +7967,7 @@ static int btrfs_dio_iomap_begin(struct + iomap->type = IOMAP_MAPPED; + } + iomap->offset = start; +- iomap->bdev = fs_info->fs_devices->latest_bdev; ++ iomap->bdev = fs_info->fs_devices->latest_dev->bdev; + iomap->length = len; + + if (write && btrfs_use_zone_append(BTRFS_I(inode), em->block_start)) +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -1705,7 +1705,7 @@ static struct dentry *btrfs_mount_root(s + goto error_close_devices; + } + +- bdev = fs_devices->latest_bdev; ++ bdev = fs_devices->latest_dev->bdev; + s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC, + fs_info); + if (IS_ERR(s)) { +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -1092,7 +1092,7 @@ void btrfs_free_extra_devids(struct btrf + list_for_each_entry(seed_dev, &fs_devices->seed_list, seed_list) + __btrfs_free_extra_devids(seed_dev, &latest_dev); + +- fs_devices->latest_bdev = latest_dev->bdev; ++ fs_devices->latest_dev = latest_dev; + + mutex_unlock(&uuid_mutex); + } +@@ -1225,7 +1225,7 @@ static int open_fs_devices(struct btrfs_ + return -EINVAL; + + fs_devices->opened = 1; +- fs_devices->latest_bdev = latest_dev->bdev; ++ fs_devices->latest_dev = latest_dev; + fs_devices->total_rw_bytes = 0; + fs_devices->chunk_alloc_policy = BTRFS_CHUNK_ALLOC_REGULAR; + fs_devices->read_policy = BTRFS_READ_POLICY_PID; +@@ -1993,7 +1993,7 @@ static struct btrfs_device * btrfs_find_ + } + + /* +- * Helper function to check if the given device is part of s_bdev / latest_bdev ++ * Helper function to check if the given device is part of s_bdev / latest_dev + * and replace it with the provided or the next active device, in the context + * where this function called, there should be always be another device (or + * this_dev) which is active. +@@ -2012,8 +2012,8 @@ void __cold btrfs_assign_next_active_dev + (fs_info->sb->s_bdev == device->bdev)) + fs_info->sb->s_bdev = next_device->bdev; + +- if (fs_info->fs_devices->latest_bdev == device->bdev) +- fs_info->fs_devices->latest_bdev = next_device->bdev; ++ if (fs_info->fs_devices->latest_dev->bdev == device->bdev) ++ fs_info->fs_devices->latest_dev = next_device; + } + + /* +--- a/fs/btrfs/volumes.h ++++ b/fs/btrfs/volumes.h +@@ -246,7 +246,11 @@ struct btrfs_fs_devices { + /* Highest generation number of seen devices */ + u64 latest_generation; + +- struct block_device *latest_bdev; ++ /* ++ * The mount device or a device with highest generation after removal ++ * or replace. ++ */ ++ struct btrfs_device *latest_dev; + + /* all of the devices in the FS, protected by a mutex + * so we can safely walk it to write out the supers without diff --git a/queue-5.15/btrfs-remove-stale-comment-about-the-btrfs_show_devname.patch b/queue-5.15/btrfs-remove-stale-comment-about-the-btrfs_show_devname.patch new file mode 100644 index 00000000000..152dcaf8380 --- /dev/null +++ b/queue-5.15/btrfs-remove-stale-comment-about-the-btrfs_show_devname.patch @@ -0,0 +1,50 @@ +From foo@baz Fri Dec 17 03:55:51 PM CET 2021 +From: Anand Jain +Date: Thu, 16 Dec 2021 21:04:13 +0800 +Subject: btrfs: remove stale comment about the btrfs_show_devname +To: linux-kernel@vger.kernel.org, stable@vger.kernel.org +Cc: linux-btrfs@vger.kernel.org, Anand Jain , David Sterba +Message-ID: <2fe0e10df7494300346f88470230a883f20753c4.1639658429.git.anand.jain@oracle.com> + +From: Anand Jain + +Commit cdccc03a8a369b59cff5e7ea3292511cfa551120 upstream. + +There were few lockdep warnings because btrfs_show_devname() was using +device_list_mutex as recorded in the commits: + + 0ccd05285e7f ("btrfs: fix a possible umount deadlock") + 779bf3fefa83 ("btrfs: fix lock dep warning, move scratch dev out of device_list_mutex and uuid_mutex") + +And finally, commit 88c14590cdd6 ("btrfs: use RCU in btrfs_show_devname +for device list traversal") removed the device_list_mutex from +btrfs_show_devname for performance reasons. + +This patch removes a stale comment about the function +btrfs_show_devname and device_list_mutex. + +Signed-off-by: Anand Jain +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/volumes.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -2312,13 +2312,6 @@ void btrfs_destroy_dev_replace_tgtdev(st + + mutex_unlock(&fs_devices->device_list_mutex); + +- /* +- * The update_dev_time() with in btrfs_scratch_superblocks() +- * may lead to a call to btrfs_show_devname() which will try +- * to hold device_list_mutex. And here this device +- * is already out of device list, so we don't have to hold +- * the device_list_mutex lock. +- */ + btrfs_scratch_superblocks(tgtdev->fs_info, tgtdev->bdev, + tgtdev->name->str); + diff --git a/queue-5.15/btrfs-update-latest_dev-when-we-create-a-sprout-device.patch b/queue-5.15/btrfs-update-latest_dev-when-we-create-a-sprout-device.patch new file mode 100644 index 00000000000..3cd3e44b75e --- /dev/null +++ b/queue-5.15/btrfs-update-latest_dev-when-we-create-a-sprout-device.patch @@ -0,0 +1,58 @@ +From foo@baz Fri Dec 17 03:55:51 PM CET 2021 +From: Anand Jain +Date: Thu, 16 Dec 2021 21:04:12 +0800 +Subject: btrfs: update latest_dev when we create a sprout device +To: linux-kernel@vger.kernel.org, stable@vger.kernel.org +Cc: linux-btrfs@vger.kernel.org, Anand Jain , Su Yue , David Sterba +Message-ID: <3cc9f5d26cf29f91b3a87df814ff84420e31080a.1639658429.git.anand.jain@oracle.com> + +From: Anand Jain + +Commit b7cb29e666fe79dda5dbe5f57fb7c92413bf161c upstream. + +When we add a device to the seed filesystem (sprouting) it is a new +filesystem (and fsid) on the device added. Update the latest_dev so +that /proc/self/mounts shows the correct device. + +Example: + + $ btrfstune -S1 /dev/vg/seed + $ mount /dev/vg/seed /btrfs + mount: /btrfs: WARNING: device write-protected, mounted read-only. + + $ cat /proc/self/mounts | grep btrfs + /dev/mapper/vg-seed /btrfs btrfs ro,relatime,space_cache,subvolid=5,subvol=/ 0 0 + + $ btrfs dev add -f /dev/vg/new /btrfs + +Before: + + $ cat /proc/self/mounts | grep btrfs + /dev/mapper/vg-seed /btrfs btrfs ro,relatime,space_cache,subvolid=5,subvol=/ 0 0 + +After: + + $ cat /proc/self/mounts | grep btrfs + /dev/mapper/vg-new /btrfs btrfs ro,relatime,space_cache,subvolid=5,subvol=/ 0 0 + +Tested-by: Su Yue +Signed-off-by: Anand Jain +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/volumes.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -2634,6 +2634,8 @@ int btrfs_init_new_device(struct btrfs_f + btrfs_abort_transaction(trans, ret); + goto error_trans; + } ++ btrfs_assign_next_active_device(fs_info->fs_devices->latest_dev, ++ device); + } + + device->fs_devices = fs_devices; diff --git a/queue-5.15/btrfs-use-latest_dev-in-btrfs_show_devname.patch b/queue-5.15/btrfs-use-latest_dev-in-btrfs_show_devname.patch new file mode 100644 index 00000000000..353d72cb90c --- /dev/null +++ b/queue-5.15/btrfs-use-latest_dev-in-btrfs_show_devname.patch @@ -0,0 +1,93 @@ +From foo@baz Fri Dec 17 03:55:51 PM CET 2021 +From: Anand Jain +Date: Thu, 16 Dec 2021 21:04:11 +0800 +Subject: btrfs: use latest_dev in btrfs_show_devname +To: linux-kernel@vger.kernel.org, stable@vger.kernel.org +Cc: linux-btrfs@vger.kernel.org, Anand Jain , Su Yue , David Sterba +Message-ID: + +From: Anand Jain + +Commit 6605fd2f394bba0a0059df2b6cfc87b0b6d393a2 upstream. + +The test case btrfs/238 reports the warning below: + + WARNING: CPU: 3 PID: 481 at fs/btrfs/super.c:2509 btrfs_show_devname+0x104/0x1e8 [btrfs] + CPU: 2 PID: 1 Comm: systemd Tainted: G W O 5.14.0-rc1-custom #72 + Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 + Call trace: + btrfs_show_devname+0x108/0x1b4 [btrfs] + show_mountinfo+0x234/0x2c4 + m_show+0x28/0x34 + seq_read_iter+0x12c/0x3c4 + vfs_read+0x29c/0x2c8 + ksys_read+0x80/0xec + __arm64_sys_read+0x28/0x34 + invoke_syscall+0x50/0xf8 + do_el0_svc+0x88/0x138 + el0_svc+0x2c/0x8c + el0t_64_sync_handler+0x84/0xe4 + el0t_64_sync+0x198/0x19c + +Reason: +While btrfs_prepare_sprout() moves the fs_devices::devices into +fs_devices::seed_list, the btrfs_show_devname() searches for the devices +and found none, leading to the warning as in above. + +Fix: +latest_dev is updated according to the changes to the device list. +That means we could use the latest_dev->name to show the device name in +/proc/self/mounts, the pointer will be always valid as it's assigned +before the device is deleted from the list in remove or replace. +The RCU protection is sufficient as the device structure is freed after +synchronization. + +Reported-by: Su Yue +Tested-by: Su Yue +Signed-off-by: Anand Jain +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/super.c | 24 +++++------------------- + 1 file changed, 5 insertions(+), 19 deletions(-) + +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2463,30 +2463,16 @@ static int btrfs_unfreeze(struct super_b + static int btrfs_show_devname(struct seq_file *m, struct dentry *root) + { + struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); +- struct btrfs_device *dev, *first_dev = NULL; + + /* +- * Lightweight locking of the devices. We should not need +- * device_list_mutex here as we only read the device data and the list +- * is protected by RCU. Even if a device is deleted during the list +- * traversals, we'll get valid data, the freeing callback will wait at +- * least until the rcu_read_unlock. ++ * There should be always a valid pointer in latest_dev, it may be stale ++ * for a short moment in case it's being deleted but still valid until ++ * the end of RCU grace period. + */ + rcu_read_lock(); +- list_for_each_entry_rcu(dev, &fs_info->fs_devices->devices, dev_list) { +- if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state)) +- continue; +- if (!dev->name) +- continue; +- if (!first_dev || dev->devid < first_dev->devid) +- first_dev = dev; +- } +- +- if (first_dev) +- seq_escape(m, rcu_str_deref(first_dev->name), " \t\n\\"); +- else +- WARN_ON(1); ++ seq_escape(m, rcu_str_deref(fs_info->fs_devices->latest_dev->name), " \t\n\\"); + rcu_read_unlock(); ++ + return 0; + } + diff --git a/queue-5.15/ceph-fix-up-non-directory-creation-in-sgid-directories.patch b/queue-5.15/ceph-fix-up-non-directory-creation-in-sgid-directories.patch new file mode 100644 index 00000000000..01a21ca1513 --- /dev/null +++ b/queue-5.15/ceph-fix-up-non-directory-creation-in-sgid-directories.patch @@ -0,0 +1,69 @@ +From fd84bfdddd169c219c3a637889a8b87f70a072c2 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 29 Nov 2021 12:16:39 +0100 +Subject: ceph: fix up non-directory creation in SGID directories + +From: Christian Brauner + +commit fd84bfdddd169c219c3a637889a8b87f70a072c2 upstream. + +Ceph always inherits the SGID bit if it is set on the parent inode, +while the generic inode_init_owner does not do this in a few cases where +it can create a possible security problem (cf. [1]). + +Update ceph to strip the SGID bit just as inode_init_owner would. + +This bug was detected by the mapped mount testsuite in [3]. The +testsuite tests all core VFS functionality and semantics with and +without mapped mounts. That is to say it functions as a generic VFS +testsuite in addition to a mapped mount testsuite. While working on +mapped mount support for ceph, SIGD inheritance was the only failing +test for ceph after the port. + +The same bug was detected by the mapped mount testsuite in XFS in +January 2021 (cf. [2]). + +[1]: commit 0fa3ecd87848 ("Fix up non-directory creation in SGID directories") +[2]: commit 01ea173e103e ("xfs: fix up non-directory creation in SGID directories") +[3]: https://git.kernel.org/fs/xfs/xfstests-dev.git + +Cc: stable@vger.kernel.org +Signed-off-by: Christian Brauner +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/file.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -603,13 +603,25 @@ static int ceph_finish_async_create(stru + in.cap.realm = cpu_to_le64(ci->i_snap_realm->ino); + in.cap.flags = CEPH_CAP_FLAG_AUTH; + in.ctime = in.mtime = in.atime = iinfo.btime; +- in.mode = cpu_to_le32((u32)mode); + in.truncate_seq = cpu_to_le32(1); + in.truncate_size = cpu_to_le64(-1ULL); + in.xattr_version = cpu_to_le64(1); + in.uid = cpu_to_le32(from_kuid(&init_user_ns, current_fsuid())); +- in.gid = cpu_to_le32(from_kgid(&init_user_ns, dir->i_mode & S_ISGID ? +- dir->i_gid : current_fsgid())); ++ if (dir->i_mode & S_ISGID) { ++ in.gid = cpu_to_le32(from_kgid(&init_user_ns, dir->i_gid)); ++ ++ /* Directories always inherit the setgid bit. */ ++ if (S_ISDIR(mode)) ++ mode |= S_ISGID; ++ else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) && ++ !in_group_p(dir->i_gid) && ++ !capable_wrt_inode_uidgid(&init_user_ns, dir, CAP_FSETID)) ++ mode &= ~S_ISGID; ++ } else { ++ in.gid = cpu_to_le32(from_kgid(&init_user_ns, current_fsgid())); ++ } ++ in.mode = cpu_to_le32((u32)mode); ++ + in.nlink = cpu_to_le32(1); + in.max_size = cpu_to_le64(lo->stripe_unit); + diff --git a/queue-5.15/dm-btree-remove-fix-use-after-free-in-rebalance_children.patch b/queue-5.15/dm-btree-remove-fix-use-after-free-in-rebalance_children.patch new file mode 100644 index 00000000000..f2a9f377284 --- /dev/null +++ b/queue-5.15/dm-btree-remove-fix-use-after-free-in-rebalance_children.patch @@ -0,0 +1,32 @@ +From 1b8d2789dad0005fd5e7d35dab26a8e1203fb6da Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Wed, 24 Nov 2021 12:07:39 -0500 +Subject: dm btree remove: fix use after free in rebalance_children() + +From: Joe Thornber + +commit 1b8d2789dad0005fd5e7d35dab26a8e1203fb6da upstream. + +Move dm_tm_unlock() after dm_tm_dec(). + +Cc: stable@vger.kernel.org +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/persistent-data/dm-btree-remove.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/persistent-data/dm-btree-remove.c ++++ b/drivers/md/persistent-data/dm-btree-remove.c +@@ -423,9 +423,9 @@ static int rebalance_children(struct sha + + memcpy(n, dm_block_data(child), + dm_bm_block_size(dm_tm_get_bm(info->tm))); +- dm_tm_unlock(info->tm, child); + + dm_tm_dec(info->tm, dm_block_location(child)); ++ dm_tm_unlock(info->tm, child); + return 0; + } + diff --git a/queue-5.15/drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdmi_to_i915.patch b/queue-5.15/drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdmi_to_i915.patch new file mode 100644 index 00000000000..c625c65d204 --- /dev/null +++ b/queue-5.15/drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdmi_to_i915.patch @@ -0,0 +1,78 @@ +From 7ceb751b615900086eed1d65955933923f127d99 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 21 Sep 2021 14:02:44 +0300 +Subject: drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jani Nikula + +commit 7ceb751b615900086eed1d65955933923f127d99 upstream. + +Prefer i915 over drm pointer. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20210921110244.8666-1-jani.nikula@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_hdmi.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -53,21 +53,20 @@ + #include "intel_panel.h" + #include "intel_snps_phy.h" + +-static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) ++static struct drm_i915_private *intel_hdmi_to_i915(struct intel_hdmi *intel_hdmi) + { +- return hdmi_to_dig_port(intel_hdmi)->base.base.dev; ++ return to_i915(hdmi_to_dig_port(intel_hdmi)->base.base.dev); + } + + static void + assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) + { +- struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); +- struct drm_i915_private *dev_priv = to_i915(dev); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(intel_hdmi); + u32 enabled_bits; + + enabled_bits = HAS_DDI(dev_priv) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; + +- drm_WARN(dev, ++ drm_WARN(&dev_priv->drm, + intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits, + "HDMI port enabled, expecting disabled\n"); + } +@@ -1246,7 +1245,7 @@ static void hsw_set_infoframes(struct in + + void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) + { +- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + struct i2c_adapter *adapter = + intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); + +@@ -1830,7 +1829,7 @@ hdmi_port_clock_valid(struct intel_hdmi + int clock, bool respect_downstream_limits, + bool has_hdmi_sink) + { +- struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + + if (clock < 25000) + return MODE_CLOCK_LOW; +@@ -1946,8 +1945,7 @@ intel_hdmi_mode_valid(struct drm_connect + struct drm_display_mode *mode) + { + struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); +- struct drm_device *dev = intel_hdmi_to_dev(hdmi); +- struct drm_i915_private *dev_priv = to_i915(dev); ++ struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + enum drm_mode_status status; + int clock = mode->clock; + int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; diff --git a/queue-5.15/drm-i915-hdmi-turn-dp-tmds-output-buffers-back-on-in-encoder-shutdown.patch b/queue-5.15/drm-i915-hdmi-turn-dp-tmds-output-buffers-back-on-in-encoder-shutdown.patch new file mode 100644 index 00000000000..7a13edac2ac --- /dev/null +++ b/queue-5.15/drm-i915-hdmi-turn-dp-tmds-output-buffers-back-on-in-encoder-shutdown.patch @@ -0,0 +1,122 @@ +From cecbc0c7eba7983965cac94f88d2db00b913253b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 29 Oct 2021 22:18:02 +0300 +Subject: drm/i915/hdmi: Turn DP++ TMDS output buffers back on in encoder->shutdown() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit cecbc0c7eba7983965cac94f88d2db00b913253b upstream. + +Looks like our VBIOS/GOP generally fail to turn the DP dual mode adater +TMDS output buffers back on after a reboot. This leads to a black screen +after reboot if we turned the TMDS output buffers off prior to reboot. +And if i915 decides to do a fastboot the black screen will persist even +after i915 takes over. + +Apparently this has been a problem ever since commit b2ccb822d376 ("drm/i915: +Enable/disable TMDS output buffers in DP++ adaptor as needed") if one +rebooted while the display was turned off. And things became worse with +commit fe0f1e3bfdfe ("drm/i915: Shut down displays gracefully on reboot") +since now we always turn the display off before a reboot. + +This was reported on a RKL, but I confirmed the same behaviour on my +SNB as well. So looks pretty universal. + +Let's fix this by explicitly turning the TMDS output buffers back on +in the encoder->shutdown() hook. Note that this gets called after irqs +have been disabled, so the i2c communication with the DP dual mode +adapter has to be performed via polling (which the gmbus code is +perfectly happy to do for us). + +We also need a bit of care in handling DDI encoders which may or may +not be set up for HDMI output. Specifically ddc_pin will not be +populated for a DP only DDI encoder, in which case we don't want to +call intel_gmbus_get_adapter(). We can handle that by simply doing +the dual mode adapter type check before calling +intel_gmbus_get_adapter(). + +Cc: # v5.11+ +Fixes: fe0f1e3bfdfe ("drm/i915: Shut down displays gracefully on reboot") +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4371 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20211029191802.18448-2-ville.syrjala@linux.intel.com +Reviewed-by: Stanislav Lisovskiy +(cherry picked from commit 49c55f7b035b87371a6d3c53d9af9f92ddc962db) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/g4x_hdmi.c | 1 + + drivers/gpu/drm/i915/display/intel_ddi.c | 1 + + drivers/gpu/drm/i915/display/intel_hdmi.c | 16 ++++++++++++++-- + drivers/gpu/drm/i915/display/intel_hdmi.h | 1 + + 4 files changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/display/g4x_hdmi.c ++++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c +@@ -584,6 +584,7 @@ void g4x_hdmi_init(struct drm_i915_priva + else + intel_encoder->enable = g4x_enable_hdmi; + } ++ intel_encoder->shutdown = intel_hdmi_encoder_shutdown; + + intel_encoder->type = INTEL_OUTPUT_HDMI; + intel_encoder->power_domain = intel_port_to_power_domain(port); +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -4432,6 +4432,7 @@ static void intel_ddi_encoder_shutdown(s + enum phy phy = intel_port_to_phy(i915, encoder->port); + + intel_dp_encoder_shutdown(encoder); ++ intel_hdmi_encoder_shutdown(encoder); + + if (!intel_phy_is_tc(i915, phy)) + return; +--- a/drivers/gpu/drm/i915/display/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.c +@@ -1246,12 +1246,13 @@ static void hsw_set_infoframes(struct in + void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) + { + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); +- struct i2c_adapter *adapter = +- intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); ++ struct i2c_adapter *adapter; + + if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) + return; + ++ adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); ++ + drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n", + enable ? "Enabling" : "Disabling"); + +@@ -2258,6 +2259,17 @@ int intel_hdmi_compute_config(struct int + return 0; + } + ++void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder) ++{ ++ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); ++ ++ /* ++ * Give a hand to buggy BIOSen which forget to turn ++ * the TMDS output buffers back on after a reboot. ++ */ ++ intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); ++} ++ + static void + intel_hdmi_unset_edid(struct drm_connector *connector) + { +--- a/drivers/gpu/drm/i915/display/intel_hdmi.h ++++ b/drivers/gpu/drm/i915/display/intel_hdmi.h +@@ -28,6 +28,7 @@ void intel_hdmi_init_connector(struct in + int intel_hdmi_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); ++void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder); + bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, + struct drm_connector *connector, + bool high_tmds_clock_ratio, diff --git a/queue-5.15/pinctrl-amd-fix-wakeups-when-irq-is-shared-with-sci.patch b/queue-5.15/pinctrl-amd-fix-wakeups-when-irq-is-shared-with-sci.patch new file mode 100644 index 00000000000..9b9004cfc77 --- /dev/null +++ b/queue-5.15/pinctrl-amd-fix-wakeups-when-irq-is-shared-with-sci.patch @@ -0,0 +1,109 @@ +From 2d54067fcd23aae61e23508425ae5b29e973573d Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Sun, 31 Oct 2021 20:48:53 -0500 +Subject: pinctrl: amd: Fix wakeups when IRQ is shared with SCI + +From: Mario Limonciello + +commit 2d54067fcd23aae61e23508425ae5b29e973573d upstream. + +On some Lenovo AMD Gen2 platforms the IRQ for the SCI and pinctrl drivers +are shared. Due to how the s2idle loop handling works, this case needs +an extra explicit check whether the interrupt was caused by SCI or by +the GPIO controller. + +To fix this rework the existing IRQ handler function to function as a +checker and an IRQ handler depending on the calling arguments. + +BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1738 +Reported-by: Joerie de Gram +Signed-off-by: Mario Limonciello +Acked-by: Basavaraj Natikar +Link: https://lore.kernel.org/r/20211101014853.6177-2-mario.limonciello@amd.com +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/pinctrl-amd.c | 29 ++++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -598,14 +598,14 @@ static struct irq_chip amd_gpio_irqchip + + #define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF)) + +-static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) ++static bool do_amd_gpio_irq_handler(int irq, void *dev_id) + { + struct amd_gpio *gpio_dev = dev_id; + struct gpio_chip *gc = &gpio_dev->gc; +- irqreturn_t ret = IRQ_NONE; + unsigned int i, irqnr; + unsigned long flags; + u32 __iomem *regs; ++ bool ret = false; + u32 regval; + u64 status, mask; + +@@ -627,6 +627,14 @@ static irqreturn_t amd_gpio_irq_handler( + /* Each status bit covers four pins */ + for (i = 0; i < 4; i++) { + regval = readl(regs + i); ++ /* caused wake on resume context for shared IRQ */ ++ if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) { ++ dev_dbg(&gpio_dev->pdev->dev, ++ "Waking due to GPIO %d: 0x%x", ++ irqnr + i, regval); ++ return true; ++ } ++ + if (!(regval & PIN_IRQ_PENDING) || + !(regval & BIT(INTERRUPT_MASK_OFF))) + continue; +@@ -650,9 +658,12 @@ static irqreturn_t amd_gpio_irq_handler( + } + writel(regval, regs + i); + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); +- ret = IRQ_HANDLED; ++ ret = true; + } + } ++ /* did not cause wake on resume context for shared IRQ */ ++ if (irq < 0) ++ return false; + + /* Signal EOI to the GPIO unit */ + raw_spin_lock_irqsave(&gpio_dev->lock, flags); +@@ -664,6 +675,16 @@ static irqreturn_t amd_gpio_irq_handler( + return ret; + } + ++static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) ++{ ++ return IRQ_RETVAL(do_amd_gpio_irq_handler(irq, dev_id)); ++} ++ ++static bool __maybe_unused amd_gpio_check_wake(void *dev_id) ++{ ++ return do_amd_gpio_irq_handler(-1, dev_id); ++} ++ + static int amd_get_groups_count(struct pinctrl_dev *pctldev) + { + struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); +@@ -1033,6 +1054,7 @@ static int amd_gpio_probe(struct platfor + goto out2; + + platform_set_drvdata(pdev, gpio_dev); ++ acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev); + + dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); + return ret; +@@ -1050,6 +1072,7 @@ static int amd_gpio_remove(struct platfo + gpio_dev = platform_get_drvdata(pdev); + + gpiochip_remove(&gpio_dev->gc); ++ acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev); + + return 0; + } diff --git a/queue-5.15/recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch b/queue-5.15/recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch new file mode 100644 index 00000000000..82d305e21c3 --- /dev/null +++ b/queue-5.15/recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch @@ -0,0 +1,36 @@ +From 85bf17b28f97ca2749968d8786dc423db320d9c2 Mon Sep 17 00:00:00 2001 +From: Jerome Marchand +Date: Fri, 10 Dec 2021 10:38:27 +0100 +Subject: recordmcount.pl: look for jgnop instruction as well as bcrl on s390 + +From: Jerome Marchand + +commit 85bf17b28f97ca2749968d8786dc423db320d9c2 upstream. + +On s390, recordmcount.pl is looking for "bcrl 0," instructions in +the objdump -d outpout. However since binutils 2.37, objdump -d +display "jgnop " for the same instruction. Update the +mcount_regex so that it accepts both. + +Signed-off-by: Jerome Marchand +Reviewed-by: Miroslav Benes +Acked-by: Steven Rostedt (VMware) +Cc: +Link: https://lore.kernel.org/r/20211210093827.1623286-1-jmarchan@redhat.com +Signed-off-by: Heiko Carstens +Signed-off-by: Greg Kroah-Hartman +--- + scripts/recordmcount.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/scripts/recordmcount.pl ++++ b/scripts/recordmcount.pl +@@ -219,7 +219,7 @@ if ($arch eq "x86_64") { + + } elsif ($arch eq "s390" && $bits == 64) { + if ($cc =~ /-DCC_USING_HOTPATCH/) { +- $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$"; ++ $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*(bcrl\\s*0,|jgnop\\s*)[0-9a-f]+ <([^\+]*)>\$"; + $mcount_adjust = 0; + } + $alignment = 8; diff --git a/queue-5.15/s390-entry-fix-duplicate-tracking-of-irq-nesting-level.patch b/queue-5.15/s390-entry-fix-duplicate-tracking-of-irq-nesting-level.patch new file mode 100644 index 00000000000..35f35e2810c --- /dev/null +++ b/queue-5.15/s390-entry-fix-duplicate-tracking-of-irq-nesting-level.patch @@ -0,0 +1,68 @@ +From c9b12b59e2ea4c3c7cedec7efb071b649652f3a9 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle +Date: Mon, 6 Dec 2021 11:50:16 +0100 +Subject: s390/entry: fix duplicate tracking of irq nesting level + +From: Sven Schnelle + +commit c9b12b59e2ea4c3c7cedec7efb071b649652f3a9 upstream. + +In the current code, when exiting from idle, rcu_irq_enter() is +called twice during irq entry: + +irq_entry_enter()-> rcu_irq_enter() +irq_enter() -> rcu_irq_enter() + +This may lead to wrong results from rcu_is_cpu_rrupt_from_idle() +because of a wrong dynticks nmi nesting count. Fix this by only +calling irq_enter_rcu(). + +Cc: # 5.12+ +Reported-by: Mark Rutland +Fixes: 56e62a737028 ("s390: convert to generic entry") +Signed-off-by: Sven Schnelle +Signed-off-by: Heiko Carstens +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kernel/irq.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/s390/kernel/irq.c ++++ b/arch/s390/kernel/irq.c +@@ -138,7 +138,7 @@ void noinstr do_io_irq(struct pt_regs *r + struct pt_regs *old_regs = set_irq_regs(regs); + int from_idle; + +- irq_enter(); ++ irq_enter_rcu(); + + if (user_mode(regs)) + update_timer_sys(); +@@ -155,7 +155,8 @@ void noinstr do_io_irq(struct pt_regs *r + do_irq_async(regs, IO_INTERRUPT); + } while (MACHINE_IS_LPAR && irq_pending(regs)); + +- irq_exit(); ++ irq_exit_rcu(); ++ + set_irq_regs(old_regs); + irqentry_exit(regs, state); + +@@ -169,7 +170,7 @@ void noinstr do_ext_irq(struct pt_regs * + struct pt_regs *old_regs = set_irq_regs(regs); + int from_idle; + +- irq_enter(); ++ irq_enter_rcu(); + + if (user_mode(regs)) + update_timer_sys(); +@@ -184,7 +185,7 @@ void noinstr do_ext_irq(struct pt_regs * + + do_irq_async(regs, EXT_INTERRUPT); + +- irq_exit(); ++ irq_exit_rcu(); + set_irq_regs(old_regs); + irqentry_exit(regs, state); + diff --git a/queue-5.15/scsi-ufs-core-retry-start_stop-on-unit_attention.patch b/queue-5.15/scsi-ufs-core-retry-start_stop-on-unit_attention.patch new file mode 100644 index 00000000000..62fbbbf6ebd --- /dev/null +++ b/queue-5.15/scsi-ufs-core-retry-start_stop-on-unit_attention.patch @@ -0,0 +1,57 @@ +From af21c3fd5b3ec540a97b367a70b26616ff7e0c55 Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Fri, 1 Oct 2021 11:20:14 -0700 +Subject: scsi: ufs: core: Retry START_STOP on UNIT_ATTENTION + +From: Jaegeuk Kim + +commit af21c3fd5b3ec540a97b367a70b26616ff7e0c55 upstream. + +Commit 57d104c153d3 ("ufs: add UFS power management support") made the UFS +driver submit a REQUEST SENSE command before submitting a power management +command to a WLUN to clear the POWER ON unit attention. Instead of +submitting a REQUEST SENSE command before submitting a power management +command, retry the power management command until it succeeds. + +This is the preparation to get rid of all UNIT ATTENTION code which should +be handled by users. + +Link: https://lore.kernel.org/r/20211001182015.1347587-2-jaegeuk@kernel.org +Cc: Adrian Hunter +Reviewed-by: Bart Van Assche +Signed-off-by: Jaegeuk Kim +Signed-off-by: Martin K. Petersen +Signed-off-by: Adrian Hunter +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/ufs/ufshcd.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -8477,7 +8477,7 @@ static int ufshcd_set_dev_pwr_mode(struc + struct scsi_sense_hdr sshdr; + struct scsi_device *sdp; + unsigned long flags; +- int ret; ++ int ret, retries; + + spin_lock_irqsave(hba->host->host_lock, flags); + sdp = hba->sdev_ufs_device; +@@ -8510,8 +8510,14 @@ static int ufshcd_set_dev_pwr_mode(struc + * callbacks hence set the RQF_PM flag so that it doesn't resume the + * already suspended childs. + */ +- ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, +- START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL); ++ for (retries = 3; retries > 0; --retries) { ++ ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, ++ START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL); ++ if (!scsi_status_is_check_condition(ret) || ++ !scsi_sense_valid(&sshdr) || ++ sshdr.sense_key != UNIT_ATTENTION) ++ break; ++ } + if (ret) { + sdev_printk(KERN_WARNING, sdp, + "START_STOP failed for power mode: %d, result %x\n", diff --git a/queue-5.15/series b/queue-5.15/series index 2621b79a344..9e4646df080 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -10,3 +10,28 @@ mac80211-mark-tx-during-stop-for-tx-in-in_reconfig.patch mac80211-send-addba-requests-using-the-tid-queue-of-the-aggregation-session.patch mac80211-validate-extended-element-id-is-present.patch firmware-arm_scpi-fix-string-overflow-in-scpi-genpd-driver.patch +bpf-fix-kernel-address-leakage-in-atomic-fetch.patch +bpf-selftests-add-test-case-for-atomic-fetch-on-spilled-pointer.patch +bpf-fix-signed-bounds-propagation-after-mov32.patch +bpf-make-32-64-bounds-propagation-slightly-more-robust.patch +bpf-selftests-add-test-case-trying-to-taint-map-value-pointer.patch +bpf-fix-kernel-address-leakage-in-atomic-cmpxchg-s-r0-aux-reg.patch +bpf-selftests-update-test-case-for-atomic-cmpxchg-on-r0-with-pointer.patch +vduse-fix-memory-corruption-in-vduse_dev_ioctl.patch +vduse-check-that-offset-is-within-bounds-in-get_config.patch +virtio_ring-fix-querying-of-maximum-dma-mapping-size-for-virtio-device.patch +vdpa-check-that-offsets-are-within-bounds.patch +s390-entry-fix-duplicate-tracking-of-irq-nesting-level.patch +recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch +arm64-dts-ten64-remove-redundant-interrupt-declaration-for-gpio-keys.patch +ceph-fix-up-non-directory-creation-in-sgid-directories.patch +dm-btree-remove-fix-use-after-free-in-rebalance_children.patch +audit-improve-robustness-of-the-audit-queue-handling.patch +btrfs-convert-latest_bdev-type-to-btrfs_device-and-rename.patch +btrfs-use-latest_dev-in-btrfs_show_devname.patch +btrfs-update-latest_dev-when-we-create-a-sprout-device.patch +btrfs-remove-stale-comment-about-the-btrfs_show_devname.patch +scsi-ufs-core-retry-start_stop-on-unit_attention.patch +drm-i915-hdmi-convert-intel_hdmi_to_dev-to-intel_hdmi_to_i915.patch +drm-i915-hdmi-turn-dp-tmds-output-buffers-back-on-in-encoder-shutdown.patch +pinctrl-amd-fix-wakeups-when-irq-is-shared-with-sci.patch diff --git a/queue-5.15/vdpa-check-that-offsets-are-within-bounds.patch b/queue-5.15/vdpa-check-that-offsets-are-within-bounds.patch new file mode 100644 index 00000000000..8db1492eca4 --- /dev/null +++ b/queue-5.15/vdpa-check-that-offsets-are-within-bounds.patch @@ -0,0 +1,37 @@ +From 3ed21c1451a14d139e1ceb18f2fa70865ce3195a Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 8 Dec 2021 13:33:37 +0300 +Subject: vdpa: check that offsets are within bounds + +From: Dan Carpenter + +commit 3ed21c1451a14d139e1ceb18f2fa70865ce3195a upstream. + +In this function "c->off" is a u32 and "size" is a long. On 64bit systems +if "c->off" is greater than "size" then "size - c->off" is a negative and +we always return -E2BIG. But on 32bit systems the subtraction is type +promoted to a high positive u32 value and basically any "c->len" is +accepted. + +Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend") +Reported-by: Xie Yongji +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20211208103337.GA4047@kili +Signed-off-by: Michael S. Tsirkin +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -197,7 +197,7 @@ static int vhost_vdpa_config_validate(st + struct vdpa_device *vdpa = v->vdpa; + long size = vdpa->config->get_config_size(vdpa); + +- if (c->len == 0) ++ if (c->len == 0 || c->off > size) + return -EINVAL; + + if (c->len > size - c->off) diff --git a/queue-5.15/vduse-check-that-offset-is-within-bounds-in-get_config.patch b/queue-5.15/vduse-check-that-offset-is-within-bounds-in-get_config.patch new file mode 100644 index 00000000000..e899052a86e --- /dev/null +++ b/queue-5.15/vduse-check-that-offset-is-within-bounds-in-get_config.patch @@ -0,0 +1,42 @@ +From dc1db0060c02d119fd4196924eff2d1129e9a442 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 8 Dec 2021 18:09:56 +0300 +Subject: vduse: check that offset is within bounds in get_config() + +From: Dan Carpenter + +commit dc1db0060c02d119fd4196924eff2d1129e9a442 upstream. + +This condition checks "len" but it does not check "offset" and that +could result in an out of bounds read if "offset > dev->config_size". +The problem is that since both variables are unsigned the +"dev->config_size - offset" subtraction would result in a very high +unsigned value. + +I think these checks might not be necessary because "len" and "offset" +are supposed to already have been validated using the +vhost_vdpa_config_validate() function. But I do not know the code +perfectly, and I like to be safe. + +Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20211208150956.GA29160@kili +Signed-off-by: Michael S. Tsirkin +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vdpa/vdpa_user/vduse_dev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/vdpa/vdpa_user/vduse_dev.c ++++ b/drivers/vdpa/vdpa_user/vduse_dev.c +@@ -655,7 +655,8 @@ static void vduse_vdpa_get_config(struct + { + struct vduse_dev *dev = vdpa_to_vduse(vdpa); + +- if (len > dev->config_size - offset) ++ if (offset > dev->config_size || ++ len > dev->config_size - offset) + return; + + memcpy(buf, dev->config + offset, len); diff --git a/queue-5.15/vduse-fix-memory-corruption-in-vduse_dev_ioctl.patch b/queue-5.15/vduse-fix-memory-corruption-in-vduse_dev_ioctl.patch new file mode 100644 index 00000000000..4d3ac4ae413 --- /dev/null +++ b/queue-5.15/vduse-fix-memory-corruption-in-vduse_dev_ioctl.patch @@ -0,0 +1,38 @@ +From ff9f9c6e74848170fcb45c8403c80d661484c8c9 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 8 Dec 2021 13:33:07 +0300 +Subject: vduse: fix memory corruption in vduse_dev_ioctl() + +From: Dan Carpenter + +commit ff9f9c6e74848170fcb45c8403c80d661484c8c9 upstream. + +The "config.offset" comes from the user. There needs to a check to +prevent it being out of bounds. The "config.offset" and +"dev->config_size" variables are both type u32. So if the offset if +out of bounds then the "dev->config_size - config.offset" subtraction +results in a very high u32 value. The out of bounds offset can result +in memory corruption. + +Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20211208103307.GA3778@kili +Signed-off-by: Michael S. Tsirkin +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vdpa/vdpa_user/vduse_dev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/vdpa/vdpa_user/vduse_dev.c ++++ b/drivers/vdpa/vdpa_user/vduse_dev.c +@@ -975,7 +975,8 @@ static long vduse_dev_ioctl(struct file + break; + + ret = -EINVAL; +- if (config.length == 0 || ++ if (config.offset > dev->config_size || ++ config.length == 0 || + config.length > dev->config_size - config.offset) + break; + diff --git a/queue-5.15/virtio_ring-fix-querying-of-maximum-dma-mapping-size-for-virtio-device.patch b/queue-5.15/virtio_ring-fix-querying-of-maximum-dma-mapping-size-for-virtio-device.patch new file mode 100644 index 00000000000..be1f0423178 --- /dev/null +++ b/queue-5.15/virtio_ring-fix-querying-of-maximum-dma-mapping-size-for-virtio-device.patch @@ -0,0 +1,56 @@ +From 817fc978b5a29b039db0418a91072b31c9aab152 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Wed, 1 Dec 2021 11:20:18 +0000 +Subject: virtio_ring: Fix querying of maximum DMA mapping size for virtio device + +From: Will Deacon + +commit 817fc978b5a29b039db0418a91072b31c9aab152 upstream. + +virtio_max_dma_size() returns the maximum DMA mapping size of the virtio +device by querying dma_max_mapping_size() for the device when the DMA +API is in use for the vring. Unfortunately, the device passed is +initialised by register_virtio_device() and does not inherit the DMA +configuration from its parent, resulting in SWIOTLB errors when bouncing +is enabled and the default 256K mapping limit (IO_TLB_SEGSIZE) is not +respected: + + | virtio-pci 0000:00:01.0: swiotlb buffer is full (sz: 294912 bytes), total 1024 (slots), used 725 (slots) + +Follow the pattern used elsewhere in the virtio_ring code when calling +into the DMA layer and pass the parent device to dma_max_mapping_size() +instead. + +Cc: Marc Zyngier +Cc: Quentin Perret +Cc: "Michael S. Tsirkin" +Cc: Jason Wang +Signed-off-by: Will Deacon +Link: https://lore.kernel.org/r/20211201112018.25276-1-will@kernel.org +Acked-by: Jason Wang +Tested-by: Suzuki K Poulose +Fixes: e6d6dd6c875e ("virtio: Introduce virtio_max_dma_size()") +Cc: Joerg Roedel +Cc: Konrad Rzeszutek Wilk +Cc: Christoph Hellwig +Cc: Robin Murphy +Signed-off-by: Steven Price +Signed-off-by: Suzuki K Poulose +Cc: stable@vger.kernel.org +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/virtio/virtio_ring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -268,7 +268,7 @@ size_t virtio_max_dma_size(struct virtio + size_t max_segment_size = SIZE_MAX; + + if (vring_use_dma_api(vdev)) +- max_segment_size = dma_max_mapping_size(&vdev->dev); ++ max_segment_size = dma_max_mapping_size(vdev->dev.parent); + + return max_segment_size; + }