From: Sasha Levin Date: Mon, 30 Dec 2024 01:33:19 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v6.1.123~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7cec1b469aa8c8d3918482515be73ad867771668;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/arm64-ensure-bits-asid-15-8-are-masked-out-when-the-.patch b/queue-5.15/arm64-ensure-bits-asid-15-8-are-masked-out-when-the-.patch new file mode 100644 index 00000000000..db4b476b97b --- /dev/null +++ b/queue-5.15/arm64-ensure-bits-asid-15-8-are-masked-out-when-the-.patch @@ -0,0 +1,65 @@ +From 04871638128a71fa7fa66cbf9f0f92acc98778a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 15:19:41 +0000 +Subject: arm64: Ensure bits ASID[15:8] are masked out when the kernel uses + 8-bit ASIDs + +From: Catalin Marinas + +[ Upstream commit c0900d15d31c2597dd9f634c8be2b71762199890 ] + +Linux currently sets the TCR_EL1.AS bit unconditionally during CPU +bring-up. On an 8-bit ASID CPU, this is RES0 and ignored, otherwise +16-bit ASIDs are enabled. However, if running in a VM and the hypervisor +reports 8-bit ASIDs (ID_AA64MMFR0_EL1.ASIDBits == 0) on a 16-bit ASIDs +CPU, Linux uses bits 8 to 63 as a generation number for tracking old +process ASIDs. The bottom 8 bits of this generation end up being written +to TTBR1_EL1 and also used for the ASID-based TLBI operations as the +upper 8 bits of the ASID. Following an ASID roll-over event we can have +threads of the same application with the same 8-bit ASID but different +generation numbers running on separate CPUs. Both TLB caching and the +TLBI operations will end up using different actual 16-bit ASIDs for the +same process. + +A similar scenario can happen in a big.LITTLE configuration if the boot +CPU only uses 8-bit ASIDs while secondary CPUs have 16-bit ASIDs. + +Ensure that the ASID generation is only tracked by bits 16 and up, +leaving bits 15:8 as 0 if the kernel uses 8-bit ASIDs. Note that +clearing TCR_EL1.AS is not sufficient since the architecture requires +that the top 8 bits of the ASID passed to TLBI instructions are 0 rather +than ignored in such configuration. + +Cc: stable@vger.kernel.org +Cc: Will Deacon +Cc: Mark Rutland +Cc: Marc Zyngier +Cc: James Morse +Acked-by: Mark Rutland +Acked-by: Marc Zyngier +Link: https://lore.kernel.org/r/20241203151941.353796-1-catalin.marinas@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/context.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c +index bbc2708fe928..d160100c8dab 100644 +--- a/arch/arm64/mm/context.c ++++ b/arch/arm64/mm/context.c +@@ -32,9 +32,9 @@ static unsigned long nr_pinned_asids; + static unsigned long *pinned_asid_map; + + #define ASID_MASK (~GENMASK(asid_bits - 1, 0)) +-#define ASID_FIRST_VERSION (1UL << asid_bits) ++#define ASID_FIRST_VERSION (1UL << 16) + +-#define NUM_USER_ASIDS ASID_FIRST_VERSION ++#define NUM_USER_ASIDS (1UL << asid_bits) + #define ctxid2asid(asid) ((asid) & ~ASID_MASK) + #define asid2ctxid(asid, genid) ((asid) | (genid)) + +-- +2.39.5 + diff --git a/queue-5.15/arm64-mm-rename-asid2idx-to-ctxid2asid.patch b/queue-5.15/arm64-mm-rename-asid2idx-to-ctxid2asid.patch new file mode 100644 index 00000000000..40b427a1fff --- /dev/null +++ b/queue-5.15/arm64-mm-rename-asid2idx-to-ctxid2asid.patch @@ -0,0 +1,110 @@ +From 6b17ecf6de3064c79db2e53eca71e31c1a4da62e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Dec 2021 09:42:25 +0800 +Subject: arm64: mm: Rename asid2idx() to ctxid2asid() + +From: Yunfeng Ye + +[ Upstream commit a3a5b763410c7bceacf41a52071134d9dc26202a ] + +The commit 0c8ea531b774 ("arm64: mm: Allocate ASIDs in pairs") introduce +the asid2idx and idx2asid macro, but these macros are not really useful +after the commit f88f42f853a8 ("arm64: context: Free up kernel ASIDs if +KPTI is not in use"). + +The code "(asid & ~ASID_MASK)" can be instead by a macro, which is the +same code with asid2idx(). So rename it to ctxid2asid() for a better +understanding. + +Also we add asid2ctxid() macro, the contextid can be generated based on +the asid and generation through this macro. + +Signed-off-by: Yunfeng Ye +Reviewed-by: Kefeng Wang +Link: https://lore.kernel.org/r/c31516eb-6d15-94e0-421c-305fc010ea79@huawei.com +Signed-off-by: Catalin Marinas +Stable-dep-of: c0900d15d31c ("arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs") +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/context.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c +index cd72576ae2b7..bbc2708fe928 100644 +--- a/arch/arm64/mm/context.c ++++ b/arch/arm64/mm/context.c +@@ -35,8 +35,8 @@ static unsigned long *pinned_asid_map; + #define ASID_FIRST_VERSION (1UL << asid_bits) + + #define NUM_USER_ASIDS ASID_FIRST_VERSION +-#define asid2idx(asid) ((asid) & ~ASID_MASK) +-#define idx2asid(idx) asid2idx(idx) ++#define ctxid2asid(asid) ((asid) & ~ASID_MASK) ++#define asid2ctxid(asid, genid) ((asid) | (genid)) + + /* Get the ASIDBits supported by the current CPU */ + static u32 get_cpu_asid_bits(void) +@@ -120,7 +120,7 @@ static void flush_context(void) + */ + if (asid == 0) + asid = per_cpu(reserved_asids, i); +- __set_bit(asid2idx(asid), asid_map); ++ __set_bit(ctxid2asid(asid), asid_map); + per_cpu(reserved_asids, i) = asid; + } + +@@ -162,7 +162,7 @@ static u64 new_context(struct mm_struct *mm) + u64 generation = atomic64_read(&asid_generation); + + if (asid != 0) { +- u64 newasid = generation | (asid & ~ASID_MASK); ++ u64 newasid = asid2ctxid(ctxid2asid(asid), generation); + + /* + * If our current ASID was active during a rollover, we +@@ -183,7 +183,7 @@ static u64 new_context(struct mm_struct *mm) + * We had a valid ASID in a previous life, so try to re-use + * it if possible. + */ +- if (!__test_and_set_bit(asid2idx(asid), asid_map)) ++ if (!__test_and_set_bit(ctxid2asid(asid), asid_map)) + return newasid; + } + +@@ -209,7 +209,7 @@ static u64 new_context(struct mm_struct *mm) + set_asid: + __set_bit(asid, asid_map); + cur_idx = asid; +- return idx2asid(asid) | generation; ++ return asid2ctxid(asid, generation); + } + + void check_and_switch_context(struct mm_struct *mm) +@@ -300,13 +300,13 @@ unsigned long arm64_mm_context_get(struct mm_struct *mm) + } + + nr_pinned_asids++; +- __set_bit(asid2idx(asid), pinned_asid_map); ++ __set_bit(ctxid2asid(asid), pinned_asid_map); + refcount_set(&mm->context.pinned, 1); + + out_unlock: + raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); + +- asid &= ~ASID_MASK; ++ asid = ctxid2asid(asid); + + /* Set the equivalent of USER_ASID_BIT */ + if (asid && arm64_kernel_unmapped_at_el0()) +@@ -327,7 +327,7 @@ void arm64_mm_context_put(struct mm_struct *mm) + raw_spin_lock_irqsave(&cpu_asid_lock, flags); + + if (refcount_dec_and_test(&mm->context.pinned)) { +- __clear_bit(asid2idx(asid), pinned_asid_map); ++ __clear_bit(ctxid2asid(asid), pinned_asid_map); + nr_pinned_asids--; + } + +-- +2.39.5 + diff --git a/queue-5.15/drm-amd-display-add-a-left-edge-pixel-if-in-ycbcr422.patch b/queue-5.15/drm-amd-display-add-a-left-edge-pixel-if-in-ycbcr422.patch new file mode 100644 index 00000000000..1be91903520 --- /dev/null +++ b/queue-5.15/drm-amd-display-add-a-left-edge-pixel-if-in-ycbcr422.patch @@ -0,0 +1,87 @@ +From 14a54868aaad5c6c93d24c5f5d5d0a5836064a05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 19:20:02 -0500 +Subject: drm/amd/display: Add a left edge pixel if in YCbCr422 or YCbCr420 and + odm + +From: Peterson Guo + +[ Upstream commit 63e7ee677c74e981257cedfdd8543510d09096ba ] + +[WHY] +On some cards when odm is used, the monitor will have 2 separate pipes +split vertically. When compression is used on the YCbCr colour space on +the second pipe to have correct colours, we need to read a pixel from the +end of first pipe to accurately display colours. Hardware was programmed +properly to account for this extra pixel but it was not calculated +properly in software causing a split screen on some monitors. + +[HOW] +The fix adjusts the second pipe's viewport and timings if the pixel +encoding is YCbCr422 or YCbCr420. + +Cc: Mario Limonciello +Cc: Alex Deucher +Cc: stable@vger.kernel.org +Reviewed-by: George Shen +Signed-off-by: Peterson Guo +Signed-off-by: Alex Hung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/dcn20/dcn20_resource.c | 23 +++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +index 04b370e7e732..6688c40f3c70 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -1899,6 +1899,7 @@ bool dcn20_split_stream_for_odm( + + if (prev_odm_pipe->plane_state) { + struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data; ++ struct output_pixel_processor *opp = next_odm_pipe->stream_res.opp; + int new_width; + + /* HACTIVE halved for odm combine */ +@@ -1932,7 +1933,28 @@ bool dcn20_split_stream_for_odm( + sd->viewport_c.x += dc_fixpt_floor(dc_fixpt_mul_int( + sd->ratios.horz_c, sd->h_active - sd->recout.x)); + sd->recout.x = 0; ++ ++ /* ++ * When odm is used in YcbCr422 or 420 colour space, a split screen ++ * will be seen with the previous calculations since the extra left ++ * edge pixel is accounted for in fmt but not in viewport. ++ * ++ * Below are calculations which fix the split by fixing the calculations ++ * if there is an extra left edge pixel. ++ */ ++ if (opp && opp->funcs->opp_get_left_edge_extra_pixel_count ++ && opp->funcs->opp_get_left_edge_extra_pixel_count( ++ opp, next_odm_pipe->stream->timing.pixel_encoding, ++ resource_is_pipe_type(next_odm_pipe, OTG_MASTER)) == 1) { ++ sd->h_active += 1; ++ sd->recout.width += 1; ++ sd->viewport.x -= dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1)); ++ sd->viewport_c.x -= dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1)); ++ sd->viewport_c.width += dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1)); ++ sd->viewport.width += dc_fixpt_ceil(dc_fixpt_mul_int(sd->ratios.horz, 1)); ++ } + } ++ + if (!next_odm_pipe->top_pipe) + next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; + else +@@ -2905,6 +2927,7 @@ bool dcn20_fast_validate_bw( + ASSERT(0); + } + } ++ + /* Actual dsc count per stream dsc validation*/ + if (!dcn20_validate_dsc(dc, context)) { + context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] = +-- +2.39.5 + diff --git a/queue-5.15/drm-dp_mst-fix-mst-sideband-message-body-length-chec.patch b/queue-5.15/drm-dp_mst-fix-mst-sideband-message-body-length-chec.patch new file mode 100644 index 00000000000..b0096a00d33 --- /dev/null +++ b/queue-5.15/drm-dp_mst-fix-mst-sideband-message-body-length-chec.patch @@ -0,0 +1,59 @@ +From afdb2d8553cdfbfd9048a07e8a021722423334ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Nov 2024 22:53:14 +0200 +Subject: drm/dp_mst: Fix MST sideband message body length check + +From: Imre Deak + +[ Upstream commit bd2fccac61b40eaf08d9546acc9fef958bfe4763 ] + +Fix the MST sideband message body length check, which must be at least 1 +byte accounting for the message body CRC (aka message data CRC) at the +end of the message. + +This fixes a case where an MST branch device returns a header with a +correct header CRC (indicating a correctly received body length), with +the body length being incorrectly set to 0. This will later lead to a +memory corruption in drm_dp_sideband_append_payload() and the following +errors in dmesg: + + UBSAN: array-index-out-of-bounds in drivers/gpu/drm/display/drm_dp_mst_topology.c:786:25 + index -1 is out of range for type 'u8 [48]' + Call Trace: + drm_dp_sideband_append_payload+0x33d/0x350 [drm_display_helper] + drm_dp_get_one_sb_msg+0x3ce/0x5f0 [drm_display_helper] + drm_dp_mst_hpd_irq_handle_event+0xc8/0x1580 [drm_display_helper] + + memcpy: detected field-spanning write (size 18446744073709551615) of single field "&msg->msg[msg->curlen]" at drivers/gpu/drm/display/drm_dp_mst_topology.c:791 (size 256) + Call Trace: + drm_dp_sideband_append_payload+0x324/0x350 [drm_display_helper] + drm_dp_get_one_sb_msg+0x3ce/0x5f0 [drm_display_helper] + drm_dp_mst_hpd_irq_handle_event+0xc8/0x1580 [drm_display_helper] + +Cc: +Cc: Lyude Paul +Reviewed-by: Lyude Paul +Signed-off-by: Imre Deak +Link: https://patchwork.freedesktop.org/patch/msgid/20241125205314.1725887-1-imre.deak@intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_dp_mst_topology.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c +index f24667a003a2..f72b4ff169a8 100644 +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -319,6 +319,9 @@ static bool drm_dp_decode_sideband_msg_hdr(const struct drm_dp_mst_topology_mgr + hdr->broadcast = (buf[idx] >> 7) & 0x1; + hdr->path_msg = (buf[idx] >> 6) & 0x1; + hdr->msg_len = buf[idx] & 0x3f; ++ if (hdr->msg_len < 1) /* min space for body CRC */ ++ return false; ++ + idx++; + hdr->somt = (buf[idx] >> 7) & 0x1; + hdr->eomt = (buf[idx] >> 6) & 0x1; +-- +2.39.5 + diff --git a/queue-5.15/drm-dp_mst-verify-request-type-in-the-corresponding-.patch b/queue-5.15/drm-dp_mst-verify-request-type-in-the-corresponding-.patch new file mode 100644 index 00000000000..9d779c0ecb7 --- /dev/null +++ b/queue-5.15/drm-dp_mst-verify-request-type-in-the-corresponding-.patch @@ -0,0 +1,83 @@ +From 4ba614d95feeb784932c22f15b6a7137f924d33f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 18:02:18 +0200 +Subject: drm/dp_mst: Verify request type in the corresponding down message + reply + +From: Imre Deak + +[ Upstream commit 4d49e77a973d3b5d1881663c3f122906a0702940 ] + +After receiving the response for an MST down request message, the +response should be accepted/parsed only if the response type matches +that of the request. Ensure this by checking if the request type code +stored both in the request and the reply match, dropping the reply in +case of a mismatch. + +This fixes the topology detection for an MST hub, as described in the +Closes link below, where the hub sends an incorrect reply message after +a CLEAR_PAYLOAD_TABLE -> LINK_ADDRESS down request message sequence. + +Cc: Lyude Paul +Cc: +Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12804 +Reviewed-by: Lyude Paul +Signed-off-by: Imre Deak +Link: https://patchwork.freedesktop.org/patch/msgid/20241203160223.2926014-3-imre.deak@intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_dp_mst_topology.c | 31 +++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c +index f72b4ff169a8..86e1a61b6b6d 100644 +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -3993,6 +3993,34 @@ drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up, + return true; + } + ++static int get_msg_request_type(u8 data) ++{ ++ return data & 0x7f; ++} ++ ++static bool verify_rx_request_type(struct drm_dp_mst_topology_mgr *mgr, ++ const struct drm_dp_sideband_msg_tx *txmsg, ++ const struct drm_dp_sideband_msg_rx *rxmsg) ++{ ++ const struct drm_dp_sideband_msg_hdr *hdr = &rxmsg->initial_hdr; ++ const struct drm_dp_mst_branch *mstb = txmsg->dst; ++ int tx_req_type = get_msg_request_type(txmsg->msg[0]); ++ int rx_req_type = get_msg_request_type(rxmsg->msg[0]); ++ char rad_str[64]; ++ ++ if (tx_req_type == rx_req_type) ++ return true; ++ ++ drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, rad_str, sizeof(rad_str)); ++ drm_dbg_kms(mgr->dev, ++ "Got unexpected MST reply, mstb: %p seqno: %d lct: %d rad: %s rx_req_type: %s (%02x) != tx_req_type: %s (%02x)\n", ++ mstb, hdr->seqno, mstb->lct, rad_str, ++ drm_dp_mst_req_type_str(rx_req_type), rx_req_type, ++ drm_dp_mst_req_type_str(tx_req_type), tx_req_type); ++ ++ return false; ++} ++ + static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) + { + struct drm_dp_sideband_msg_tx *txmsg; +@@ -4022,6 +4050,9 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) + goto out_clear_reply; + } + ++ if (!verify_rx_request_type(mgr, txmsg, msg)) ++ goto out_clear_reply; ++ + drm_dp_sideband_parse_reply(mgr, msg, &txmsg->reply); + + if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) { +-- +2.39.5 + diff --git a/queue-5.15/ksmbd-fix-out-of-bounds-read-in-ksmbd_vfs_stream_rea.patch b/queue-5.15/ksmbd-fix-out-of-bounds-read-in-ksmbd_vfs_stream_rea.patch new file mode 100644 index 00000000000..03cdddbf0d5 --- /dev/null +++ b/queue-5.15/ksmbd-fix-out-of-bounds-read-in-ksmbd_vfs_stream_rea.patch @@ -0,0 +1,42 @@ +From 9714cd5a17dc9753247b0ced2f94b0dcf63f6e78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:32:45 +0900 +Subject: ksmbd: fix Out-of-Bounds Read in ksmbd_vfs_stream_read + +From: Jordy Zomer + +[ Upstream commit fc342cf86e2dc4d2edb0fc2ff5e28b6c7845adb9 ] + +An offset from client could be a negative value, It could lead +to an out-of-bounds read from the stream_buf. +Note that this issue is coming when setting +'vfs objects = streams_xattr parameter' in ksmbd.conf. + +Cc: stable@vger.kernel.org # v5.15+ +Reported-by: Jordy Zomer +Signed-off-by: Jordy Zomer +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/smb2pdu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c +index 54f7cf7a98b2..35914c9809aa 100644 +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -6350,6 +6350,10 @@ int smb2_read(struct ksmbd_work *work) + } + + offset = le64_to_cpu(req->Offset); ++ if (offset < 0) { ++ err = -EINVAL; ++ goto out; ++ } + length = le32_to_cpu(req->Length); + mincount = le32_to_cpu(req->MinimumCount); + +-- +2.39.5 + diff --git a/queue-5.15/ksmbd-fix-out-of-bounds-write-in-ksmbd_vfs_stream_wr.patch b/queue-5.15/ksmbd-fix-out-of-bounds-write-in-ksmbd_vfs_stream_wr.patch new file mode 100644 index 00000000000..3242629e630 --- /dev/null +++ b/queue-5.15/ksmbd-fix-out-of-bounds-write-in-ksmbd_vfs_stream_wr.patch @@ -0,0 +1,40 @@ +From 2e95e6605e31a157f72d55f00f99893b69d17830 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:33:25 +0900 +Subject: ksmbd: fix Out-of-Bounds Write in ksmbd_vfs_stream_write + +From: Jordy Zomer + +[ Upstream commit 313dab082289e460391c82d855430ec8a28ddf81 ] + +An offset from client could be a negative value, It could allows +to write data outside the bounds of the allocated buffer. +Note that this issue is coming when setting +'vfs objects = streams_xattr parameter' in ksmbd.conf. + +Cc: stable@vger.kernel.org # v5.15+ +Reported-by: Jordy Zomer +Signed-off-by: Jordy Zomer +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/smb2pdu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c +index 35914c9809aa..0f97830d1ebc 100644 +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -6567,6 +6567,8 @@ int smb2_write(struct ksmbd_work *work) + } + + offset = le64_to_cpu(req->Offset); ++ if (offset < 0) ++ return -EINVAL; + length = le32_to_cpu(req->Length); + + if (req->Channel == SMB2_CHANNEL_RDMA_V1 || +-- +2.39.5 + diff --git a/queue-5.15/ksmbd-fix-racy-issue-from-session-lookup-and-expire.patch b/queue-5.15/ksmbd-fix-racy-issue-from-session-lookup-and-expire.patch new file mode 100644 index 00000000000..7fa1b062d93 --- /dev/null +++ b/queue-5.15/ksmbd-fix-racy-issue-from-session-lookup-and-expire.patch @@ -0,0 +1,207 @@ +From 51114fe549f64667b7eb9ef294c5a08c0c3dcdd0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 21:38:47 +0900 +Subject: ksmbd: fix racy issue from session lookup and expire + +From: Namjae Jeon + +[ Upstream commit b95629435b84b9ecc0c765995204a4d8a913ed52 ] + +Increment the session reference count within the lock for lookup to avoid +racy issue with session expire. + +Cc: stable@vger.kernel.org +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-25737 +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/auth.c | 2 ++ + fs/ksmbd/mgmt/user_session.c | 6 +++++- + fs/ksmbd/server.c | 4 ++-- + fs/ksmbd/smb2pdu.c | 27 ++++++++++++++------------- + 4 files changed, 23 insertions(+), 16 deletions(-) + +diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c +index 9a08e6a90b94..3b776b5de7db 100644 +--- a/fs/ksmbd/auth.c ++++ b/fs/ksmbd/auth.c +@@ -1010,6 +1010,8 @@ static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id, + + ses_enc_key = enc ? sess->smb3encryptionkey : + sess->smb3decryptionkey; ++ if (enc) ++ ksmbd_user_session_get(sess); + memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE); + + return 0; +diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c +index 844db95e6651..1cee9733bdac 100644 +--- a/fs/ksmbd/mgmt/user_session.c ++++ b/fs/ksmbd/mgmt/user_session.c +@@ -257,8 +257,10 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, + + down_read(&conn->session_lock); + sess = xa_load(&conn->sessions, id); +- if (sess) ++ if (sess) { + sess->last_active = jiffies; ++ ksmbd_user_session_get(sess); ++ } + up_read(&conn->session_lock); + return sess; + } +@@ -269,6 +271,8 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id) + + down_read(&sessions_table_lock); + sess = __session_lookup(id); ++ if (sess) ++ ksmbd_user_session_get(sess); + up_read(&sessions_table_lock); + + return sess; +diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c +index da5b9678ad05..27d8d6c6fdac 100644 +--- a/fs/ksmbd/server.c ++++ b/fs/ksmbd/server.c +@@ -241,14 +241,14 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, + if (work->tcon) + ksmbd_tree_connect_put(work->tcon); + smb3_preauth_hash_rsp(work); +- if (work->sess) +- ksmbd_user_session_put(work->sess); + if (work->sess && work->sess->enc && work->encrypted && + conn->ops->encrypt_resp) { + rc = conn->ops->encrypt_resp(work); + if (rc < 0) + conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); + } ++ if (work->sess) ++ ksmbd_user_session_put(work->sess); + + ksmbd_conn_write(work); + } +diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c +index 0f97830d1ebc..7f9297a5f3ef 100644 +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -67,8 +67,10 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id) + return false; + + sess = ksmbd_session_lookup_all(conn, id); +- if (sess) ++ if (sess) { ++ ksmbd_user_session_put(sess); + return true; ++ } + pr_err("Invalid user session id: %llu\n", id); + return false; + } +@@ -606,10 +608,8 @@ int smb2_check_user_session(struct ksmbd_work *work) + + /* Check for validity of user session */ + work->sess = ksmbd_session_lookup_all(conn, sess_id); +- if (work->sess) { +- ksmbd_user_session_get(work->sess); ++ if (work->sess) + return 1; +- } + ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id); + return -ENOENT; + } +@@ -1722,29 +1722,35 @@ int smb2_sess_setup(struct ksmbd_work *work) + + if (conn->dialect != sess->dialect) { + rc = -EINVAL; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) { + rc = -EINVAL; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (strncmp(conn->ClientGUID, sess->ClientGUID, + SMB2_CLIENT_GUID_SIZE)) { + rc = -ENOENT; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (sess->state == SMB2_SESSION_IN_PROGRESS) { + rc = -EACCES; ++ ksmbd_user_session_put(sess); + goto out_err; + } + + if (sess->state == SMB2_SESSION_EXPIRED) { + rc = -EFAULT; ++ ksmbd_user_session_put(sess); + goto out_err; + } ++ ksmbd_user_session_put(sess); + + if (ksmbd_conn_need_reconnect(conn)) { + rc = -EFAULT; +@@ -1752,7 +1758,8 @@ int smb2_sess_setup(struct ksmbd_work *work) + goto out_err; + } + +- if (ksmbd_session_lookup(conn, sess_id)) { ++ sess = ksmbd_session_lookup(conn, sess_id); ++ if (!sess) { + rc = -EACCES; + goto out_err; + } +@@ -1763,7 +1770,6 @@ int smb2_sess_setup(struct ksmbd_work *work) + } + + conn->binding = true; +- ksmbd_user_session_get(sess); + } else if ((conn->dialect < SMB30_PROT_ID || + server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && + (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { +@@ -1790,7 +1796,6 @@ int smb2_sess_setup(struct ksmbd_work *work) + } + + conn->binding = false; +- ksmbd_user_session_get(sess); + } + work->sess = sess; + +@@ -2202,9 +2207,9 @@ int smb2_tree_disconnect(struct ksmbd_work *work) + int smb2_session_logoff(struct ksmbd_work *work) + { + struct ksmbd_conn *conn = work->conn; ++ struct ksmbd_session *sess = work->sess; + struct smb2_logoff_req *req; + struct smb2_logoff_rsp *rsp; +- struct ksmbd_session *sess; + u64 sess_id; + int err; + +@@ -2226,11 +2231,6 @@ int smb2_session_logoff(struct ksmbd_work *work) + ksmbd_close_session_fds(work); + ksmbd_conn_wait_idle(conn, sess_id); + +- /* +- * Re-lookup session to validate if session is deleted +- * while waiting request complete +- */ +- sess = ksmbd_session_lookup_all(conn, sess_id); + if (ksmbd_tree_conn_session_logoff(sess)) { + ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); + rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; +@@ -8660,6 +8660,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) + le64_to_cpu(tr_hdr->SessionId)); + return -ECONNABORTED; + } ++ ksmbd_user_session_put(sess); + + iov[0].iov_base = buf; + iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; +-- +2.39.5 + diff --git a/queue-5.15/lib-stackinit-hide-never-taken-branch-from-compiler.patch b/queue-5.15/lib-stackinit-hide-never-taken-branch-from-compiler.patch new file mode 100644 index 00000000000..6666739a0c5 --- /dev/null +++ b/queue-5.15/lib-stackinit-hide-never-taken-branch-from-compiler.patch @@ -0,0 +1,45 @@ +From 26a524f5bd8f3ad36ca412ec745c9b541fc5aeae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Nov 2024 03:38:13 -0800 +Subject: lib: stackinit: hide never-taken branch from compiler + +From: Kees Cook + +[ Upstream commit 5c3793604f91123bf49bc792ce697a0bef4c173c ] + +The never-taken branch leads to an invalid bounds condition, which is by +design. To avoid the unwanted warning from the compiler, hide the +variable from the optimizer. + +../lib/stackinit_kunit.c: In function 'do_nothing_u16_zero': +../lib/stackinit_kunit.c:51:49: error: array subscript 1 is outside array bounds of 'u16[0]' {aka 'short unsigned int[]'} [-Werror=array-bounds=] + 51 | #define DO_NOTHING_RETURN_SCALAR(ptr) *(ptr) + | ^~~~~~ +../lib/stackinit_kunit.c:219:24: note: in expansion of macro 'DO_NOTHING_RETURN_SCALAR' + 219 | return DO_NOTHING_RETURN_ ## which(ptr + 1); \ + | ^~~~~~~~~~~~~~~~~~ + +Link: https://lkml.kernel.org/r/20241117113813.work.735-kees@kernel.org +Signed-off-by: Kees Cook +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + lib/test_stackinit.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/test_stackinit.c b/lib/test_stackinit.c +index a3c74e6a21ff..56653c6a2a61 100644 +--- a/lib/test_stackinit.c ++++ b/lib/test_stackinit.c +@@ -259,6 +259,7 @@ static noinline __init int test_ ## name (void) \ + static noinline __init DO_NOTHING_TYPE_ ## which(var_type) \ + do_nothing_ ## name(var_type *ptr) \ + { \ ++ OPTIMIZER_HIDE_VAR(ptr); \ + /* Will always be true, but compiler doesn't know. */ \ + if ((unsigned long)ptr > 0x2) \ + return DO_NOTHING_RETURN_ ## which(ptr); \ +-- +2.39.5 + diff --git a/queue-5.15/riscv-fix-ipis-usage-in-kfence_protect_page.patch b/queue-5.15/riscv-fix-ipis-usage-in-kfence_protect_page.patch new file mode 100644 index 00000000000..228d396a995 --- /dev/null +++ b/queue-5.15/riscv-fix-ipis-usage-in-kfence_protect_page.patch @@ -0,0 +1,86 @@ +From 89e3d877fe251e0610c885b362c0db27494ad3b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2024 08:41:25 +0100 +Subject: riscv: Fix IPIs usage in kfence_protect_page() + +From: Alexandre Ghiti + +[ Upstream commit b3431a8bb336cece8adc452437befa7d4534b2fd ] + +flush_tlb_kernel_range() may use IPIs to flush the TLBs of all the +cores, which triggers the following warning when the irqs are disabled: + +[ 3.455330] WARNING: CPU: 1 PID: 0 at kernel/smp.c:815 smp_call_function_many_cond+0x452/0x520 +[ 3.456647] Modules linked in: +[ 3.457218] CPU: 1 UID: 0 PID: 0 Comm: swapper/1 Not tainted 6.12.0-rc7-00010-g91d3de7240b8 #1 +[ 3.457416] Hardware name: QEMU QEMU Virtual Machine, BIOS +[ 3.457633] epc : smp_call_function_many_cond+0x452/0x520 +[ 3.457736] ra : on_each_cpu_cond_mask+0x1e/0x30 +[ 3.457786] epc : ffffffff800b669a ra : ffffffff800b67c2 sp : ff2000000000bb50 +[ 3.457824] gp : ffffffff815212b8 tp : ff6000008014f080 t0 : 000000000000003f +[ 3.457859] t1 : ffffffff815221e0 t2 : 000000000000000f s0 : ff2000000000bc10 +[ 3.457920] s1 : 0000000000000040 a0 : ffffffff815221e0 a1 : 0000000000000001 +[ 3.457953] a2 : 0000000000010000 a3 : 0000000000000003 a4 : 0000000000000000 +[ 3.458006] a5 : 0000000000000000 a6 : ffffffffffffffff a7 : 0000000000000000 +[ 3.458042] s2 : ffffffff815223be s3 : 00fffffffffff000 s4 : ff600001ffe38fc0 +[ 3.458076] s5 : ff600001ff950d00 s6 : 0000000200000120 s7 : 0000000000000001 +[ 3.458109] s8 : 0000000000000001 s9 : ff60000080841ef0 s10: 0000000000000001 +[ 3.458141] s11: ffffffff81524812 t3 : 0000000000000001 t4 : ff60000080092bc0 +[ 3.458172] t5 : 0000000000000000 t6 : ff200000000236d0 +[ 3.458203] status: 0000000200000100 badaddr: ffffffff800b669a cause: 0000000000000003 +[ 3.458373] [] smp_call_function_many_cond+0x452/0x520 +[ 3.458593] [] on_each_cpu_cond_mask+0x1e/0x30 +[ 3.458625] [] __flush_tlb_range+0x118/0x1ca +[ 3.458656] [] flush_tlb_kernel_range+0x1e/0x26 +[ 3.458683] [] kfence_protect+0xc0/0xce +[ 3.458717] [] kfence_guarded_free+0xc6/0x1c0 +[ 3.458742] [] __kfence_free+0x62/0xc6 +[ 3.458764] [] kfree+0x106/0x32c +[ 3.458786] [] detach_buf_split+0x188/0x1a8 +[ 3.458816] [] virtqueue_get_buf_ctx+0xb6/0x1f6 +[ 3.458839] [] virtqueue_get_buf+0xe/0x16 +[ 3.458880] [] virtblk_done+0x5c/0xe2 +[ 3.458908] [] vring_interrupt+0x6a/0x74 +[ 3.458930] [] __handle_irq_event_percpu+0x7c/0xe2 +[ 3.458956] [] handle_irq_event+0x3c/0x86 +[ 3.458978] [] handle_simple_irq+0x9e/0xbe +[ 3.459004] [] generic_handle_domain_irq+0x1c/0x2a +[ 3.459027] [] imsic_handle_irq+0xba/0x120 +[ 3.459056] [] generic_handle_domain_irq+0x1c/0x2a +[ 3.459080] [] riscv_intc_aia_irq+0x24/0x34 +[ 3.459103] [] handle_riscv_irq+0x2e/0x4c +[ 3.459133] [] call_on_irq_stack+0x32/0x40 + +So only flush the local TLB and let the lazy kfence page fault handling +deal with the faults which could happen when a core has an old protected +pte version cached in its TLB. That leads to potential inaccuracies which +can be tolerated when using kfence. + +Fixes: 47513f243b45 ("riscv: Enable KFENCE for riscv64") +Signed-off-by: Alexandre Ghiti +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20241209074125.52322-1-alexghiti@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/kfence.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/riscv/include/asm/kfence.h b/arch/riscv/include/asm/kfence.h +index d887a54042aa..5d013dc52c0b 100644 +--- a/arch/riscv/include/asm/kfence.h ++++ b/arch/riscv/include/asm/kfence.h +@@ -55,7 +55,9 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) + else + set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); + +- flush_tlb_kernel_range(addr, addr + PAGE_SIZE); ++ preempt_disable(); ++ local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE); ++ preempt_enable(); + + return true; + } +-- +2.39.5 + diff --git a/queue-5.15/series b/queue-5.15/series index 5138ce8cf41..09659910215 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -85,3 +85,13 @@ virtio-blk-don-t-keep-queue-frozen-during-system-sus.patch vmalloc-fix-accounting-with-i915.patch mips-probe-toolchain-support-of-msym32.patch bpf-check-validity-of-link-type-in-bpf_link_show_fdi.patch +drm-dp_mst-fix-mst-sideband-message-body-length-chec.patch +ksmbd-fix-out-of-bounds-read-in-ksmbd_vfs_stream_rea.patch +ksmbd-fix-out-of-bounds-write-in-ksmbd_vfs_stream_wr.patch +drm-amd-display-add-a-left-edge-pixel-if-in-ycbcr422.patch +arm64-mm-rename-asid2idx-to-ctxid2asid.patch +arm64-ensure-bits-asid-15-8-are-masked-out-when-the-.patch +drm-dp_mst-verify-request-type-in-the-corresponding-.patch +lib-stackinit-hide-never-taken-branch-from-compiler.patch +ksmbd-fix-racy-issue-from-session-lookup-and-expire.patch +riscv-fix-ipis-usage-in-kfence_protect_page.patch