From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21FC73F1AB2 for ; Wed, 17 Jun 2026 12:46:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781700403; cv=none; b=RcFmF/R4tB8hySTWJINGcDq3CAhiqDLzCQOiunPg14z9JypiwQhFqLrXFxpGEbsw0fb79ewJSWH+leAm1s/q0iz7d/Lti/gx4x9ZROyoYJRlRcNRWUY+8G6Bf+L27prUqL+TTYJN+kU+4ENnt8puR/YMwxtAtfrLgfsdufnAtbE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781700403; c=relaxed/simple; bh=wvbdn8cdaJEOzC5iNSIzglBW5dAGJSnIb5ck1dc/4bA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ky2mTtg/6/UlnysNpRtODBklRq3xVrnbInlwAecD0zyBI2ww9f7pK89HdMBvfhpSMdmZ9kDlRkURU3STctoDPX9Cf1E5QGVLEfBnZdXbnWnOPUEHzQvSLauIf3CMpei+0KCkGI49AheLge7q9RVHqd5tjNwwU31h46KODEfbEE8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RZ6rYVGS; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RZ6rYVGS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70FAD1F00A3E; Wed, 17 Jun 2026 12:46:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1781700402; bh=eQQ6wSgjF6ER+NIxhl7VmB0BbetjKmD6208NW4EP8xw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=RZ6rYVGSG5I/VTFFMgAqvhxd85LKmWsewuP0PYA6yNmsJNI5c48uBziLGJPMOp8Mj Rt2ODIpSUK4drpJTOISuipLUfmrSOuz+62XRKchbaJ0/vsLHGNON58EKZTWmP+amdt koEftnDivUNxCPhMiy5DVj1pZe1I8zQbIKx2q5FhclQT2G1Z1slochIiLEmRcLFoh3 gE3mADcTE4r8rUlFr0y35RH9i/sW2t/TnOZJAgDhI17D/qhjNqa54gzqR35auAP5F3 hv/BD3+J74fNfhWQQgGYdp9/WDZDTZM8Ld8aFVoc2g56M62gBIEDjP0IW1EKYEcH8a ood/NcCHmSVQA== From: Sasha Levin To: stable@vger.kernel.org Cc: Tudor Ambarus , Titouan Ameline de Cadeville , Krzysztof Kozlowski , Sasha Levin Subject: [PATCH 6.18.y 2/3] firmware: samsung: acpm: Fix cross-thread RX length corruption Date: Wed, 17 Jun 2026 08:46:38 -0400 Message-ID: <20260617124639.3857566-2-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260617124639.3857566-1-sashal@kernel.org> References: <2026061536-unchain-squabble-5291@gregkh> <20260617124639.3857566-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Tudor Ambarus [ Upstream commit f133bd4b5daf71bccdde0ad1a4f47fac76a6bfb1 ] Sashiko identified a cross-thread RX length corruption bug when reviewing the thermal addition to ACPM [1]. When multiple threads concurrently send IPC requests, the ACPM polling mechanism can encounter responses belonging to other threads. To drain the queue, the driver saves these concurrent responses into an internal cache (`rx_data->cmd`) to be retrieved later by the owning thread. Previously, the driver incorrectly used `xfer->rxcnt` (the expected receive length of the *current* polling thread) when copying data for *other* threads into this cache. If the threads expected responses of different lengths, this resulted in buffer underflows (leading to reads of uninitialized memory) or potential buffer overflows. Fix this by replacing the boolean `response` flag in `struct acpm_rx_data` with `rxcnt`, caching the exact expected receive length for each specific transaction during transfer preparation. Use this cached length when saving concurrent responses. Consequently, ensure that `xfer->rxcnt` is explicitly zeroed in driver helpers (e.g., `acpm_dvfs_set_xfer`) for fire-and-forget messages to prevent uninitialized stack garbage from being interpreted as a massive expected receive length. Cc: stable@vger.kernel.org Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver") Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1] Reported-by: Titouan Ameline de Cadeville Closes: https://lore.kernel.org/r/20260426210255.73674-1-titouan.ameline@gmail.com/ Signed-off-by: Tudor Ambarus Link: https://patch.msgid.link/20260505-acpm-fixes-sashiko-reports-v5-1-43b5ee7f1674@linaro.org Signed-off-by: Krzysztof Kozlowski Stable-dep-of: c889b1464788 ("firmware: samsung: acpm: Fix false timeouts and Use-After-Free in polling") Signed-off-by: Sasha Levin --- drivers/firmware/samsung/exynos-acpm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c index 07bb4af1ca5845..742c0093250435 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -103,12 +103,12 @@ struct acpm_queue { * * @cmd: pointer to where the data shall be saved. * @n_cmd: number of 32-bit commands. - * @response: true if the client expects the RX data. + * @rxcnt: expected length of the response in 32-bit words. */ struct acpm_rx_data { u32 *cmd; size_t n_cmd; - bool response; + size_t rxcnt; }; #define ACPM_SEQNUM_MAX 64 @@ -196,7 +196,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan, const struct acpm_rx_data *rx_data = &achan->rx_data[tx_seqnum - 1]; u32 rx_seqnum; - if (!rx_data->response) + if (!rx_data->rxcnt) return; rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]); @@ -253,7 +253,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) seqnum = rx_seqnum - 1; rx_data = &achan->rx_data[seqnum]; - if (rx_data->response) { + if (rx_data->rxcnt) { if (rx_seqnum == tx_seqnum) { __ioread32_copy(xfer->rxd, addr, xfer->rxcnt); rx_set = true; @@ -265,7 +265,8 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) * clear yet the bitmap. It will be cleared * after the response is copied to the request. */ - __ioread32_copy(rx_data->cmd, addr, xfer->rxcnt); + __ioread32_copy(rx_data->cmd, addr, + rx_data->rxcnt); } } else { clear_bit(seqnum, achan->bitmap_seqnum); @@ -377,8 +378,8 @@ static void acpm_prepare_xfer(struct acpm_chan *achan, /* Clear data for upcoming responses */ rx_data = &achan->rx_data[achan->seqnum - 1]; memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd); - if (xfer->rxd) - rx_data->response = true; + /* zero means no response expected */ + rx_data->rxcnt = xfer->rxcnt; /* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */ set_bit(achan->seqnum - 1, achan->bitmap_seqnum); -- 2.53.0