From nobody Mon Jun 8 19:35:23 2026 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 8D9A03845CB for ; Wed, 27 May 2026 03:40:35 +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=1779853236; cv=none; b=h51YM+Zc6/hh6eNYrzE9q48xFLhwOjo8FeS2XwAcsckkpKw3P3DwWJytc9ZtZ/kV1Y2aAOf5poDAexVs0+c7ItmyLpWTHVB6b/PurxqsF8bI8GNndpAWNHEVqUoz5j1WTa6dXjPqsHtoIwKuxvu8hAV0AD7Q+/YJMYUIpbNAtaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779853236; c=relaxed/simple; bh=CXhDB0KPxO7GkLYsVv+aDl4cqH0/ybNdF+Sm+F3HNN8=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=WTEJAADZ8MiWtzDodaf/z9+sa9rI1Od2d6I/ouiydL+jWC+wgwiDWXh7Z5SsqhIvadTTBpd01auAZpwAEskmCzK5uWPyYw/YxTcLtsGkAsSQL/8NTTNpyZ8aXnnv3ODJdeGnoCaCKhVdEzZG7KEFpTDgMzWJVJFPAVU0rwyWG8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IuLjJ7/h; 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="IuLjJ7/h" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CB12A1F000E9; Wed, 27 May 2026 03:40:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779853235; bh=qd2/rVmrTYgOaBd0eapTai8v1HXcat4DJMFOI3XxKW0=; h=From:To:Cc:Subject:Date; b=IuLjJ7/hthSifd8/+TGY+QgdDN7eIsXLt1xdKIX4a45hXT/8BNHfz0qgXuFLbY6Hy DS/GwH6MrHkpryu2LL5ZayCvl7v6PNm4fO3HCuh0jgN/swGrpxKIM2Rqau1KNzWnjT WnUwhW72QcrBpZy0ehhS6vuLv4XjlhwgLJqi90akdbLK1u+G+s5AiZymBvGOQjOa3f aiVEzKEYX6TrgvwJ8ga7d7340PyTlAPPK565jKsL2NvexY3v4477ToAgkfl9dzzqod Wb7LHuC7vM7AznXeJZmlsckbBCbhTvk2gS2IFvmvKBMm92FBnkqXW0XFCglSa98S/P jT50dF3FVGyOA== From: Dinh Nguyen To: linux-kernel@vger.kernel.org Cc: dinguyen@kernel.org, Markus.Elfring@web.de, tze.yee.ng@altera.com, stable@kernel.org Subject: [PATCHv2 RESEND] firmware: stratix10-rsu: Fix NULL deref on rsu_send_msg() timeout in probe Date: Tue, 26 May 2026 22:40:24 -0500 Message-ID: <20260527034024.27524-1-dinguyen@kernel.org> X-Mailer: git-send-email 2.42.0.411.g813d9a9188 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" rsu_send_msg() can return -ETIMEDOUT when wait_for_completion_interruptible_timeout() fires while the SMC call is sti= ll pending. In stratix10_rsu_probe(), the error paths for COMMAND_RSU_DCMF_VER= SION, COMMAND_RSU_DCMF_STATUS, COMMAND_RSU_MAX_RETRY and COMMAND_RSU_GET_SPT_TABLE call stratix10_svc_free_channel() - which sets chan->scl to NULL - but then fall through and queue the next request on the same channel. The next svc kthread that runs will dereference pdata->chan->scl in its receive callback path, triggering a NULL pointer dereference identical to the one fixed by commit c45f7263100c ("firmware: stratix10-rsu: Fix NULL pointer dereference when RSU is disabled") for the COMMAND_RSU_STATUS path. Apply the same cleanup pattern to the remaining failure paths: remove the async client, free the channel, and return early so no further messages are queued on a channel whose scl has been cleared. While at it, clean up stratix10_rsu_probe() in two ways without changing behavior: - Drop redundant zero-initialization of fields already cleared by devm_kzalloc(): client.receive_cb, status.* and spt0/1_address (INVALID_SPT_ADDRESS is 0x0). - Replace five identical 3-line error-cleanup blocks (stratix10_svc_remove_async_client() + stratix10_svc_free_channel() + return ret) with goto labels (remove_async_client, free_channel), matching the standard kernel resource-unwinding pattern and making it easier to extend the probe sequence without forgetting matching cleanup. Also move init_completion() next to mutex_init() so sync-primitive initialization is grouped before anything that could trigger a callback. Fixes: 15847537b623 ("firmware: stratix10-rsu: Migrate RSU driver to use st= ratix10 asynchronous framework.") Cc: stable@kernel.org Assisted-by: Claude:claude-4.7-opus-high Cursor Signed-off-by: Dinh Nguyen --- v2: Add a minor clean-up of the function stratix10_rsu_probe() to have a centralize exit for all the rsu_send_async_msg() and rsu_send_msg(). --- drivers/firmware/stratix10-rsu.c | 45 ++++++++++++++------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-= rsu.c index e1912108a0fee..2a7a0f7743893 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -723,15 +723,9 @@ static int stratix10_rsu_probe(struct platform_device = *pdev) return -ENOMEM; =20 priv->client.dev =3D dev; - priv->client.receive_cb =3D NULL; priv->client.priv =3D priv; - priv->status.current_image =3D 0; - priv->status.fail_image =3D 0; - priv->status.error_location =3D 0; - priv->status.error_details =3D 0; - priv->status.version =3D 0; - priv->status.state =3D 0; priv->retry_counter =3D INVALID_RETRY_COUNTER; + priv->max_retry =3D INVALID_RETRY_COUNTER; priv->dcmf_version.dcmf0 =3D INVALID_DCMF_VERSION; priv->dcmf_version.dcmf1 =3D INVALID_DCMF_VERSION; priv->dcmf_version.dcmf2 =3D INVALID_DCMF_VERSION; @@ -740,11 +734,11 @@ static int stratix10_rsu_probe(struct platform_device= *pdev) priv->dcmf_status.dcmf1 =3D INVALID_DCMF_STATUS; priv->dcmf_status.dcmf2 =3D INVALID_DCMF_STATUS; priv->dcmf_status.dcmf3 =3D INVALID_DCMF_STATUS; - priv->max_retry =3D INVALID_RETRY_COUNTER; - priv->spt0_address =3D INVALID_SPT_ADDRESS; - priv->spt1_address =3D INVALID_SPT_ADDRESS; + /* spt0/1_address and status fields default to 0 from kzalloc */ =20 mutex_init(&priv->lock); + init_completion(&priv->completion); + priv->chan =3D stratix10_svc_request_channel_byname(&priv->client, SVC_CLIENT_RSU); if (IS_ERR(priv->chan)) { @@ -756,11 +750,9 @@ static int stratix10_rsu_probe(struct platform_device = *pdev) ret =3D stratix10_svc_add_async_client(priv->chan, false); if (ret) { dev_err(dev, "failed to add async client\n"); - stratix10_svc_free_channel(priv->chan); - return ret; + goto free_channel; } =20 - init_completion(&priv->completion); platform_set_drvdata(pdev, priv); =20 /* get the initial state from firmware */ @@ -768,41 +760,44 @@ static int stratix10_rsu_probe(struct platform_device= *pdev) rsu_async_status_callback); if (ret) { dev_err(dev, "Error, getting RSU status %i\n", ret); - stratix10_svc_remove_async_client(priv->chan); - stratix10_svc_free_channel(priv->chan); - return ret; + goto remove_async_client; } =20 /* get DCMF version from firmware */ - ret =3D rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION, - 0, rsu_dcmf_version_callback); + ret =3D rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION, 0, + rsu_dcmf_version_callback); if (ret) { dev_err(dev, "Error, getting DCMF version %i\n", ret); - stratix10_svc_free_channel(priv->chan); + goto remove_async_client; } =20 - ret =3D rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS, - 0, rsu_dcmf_status_callback); + ret =3D rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS, 0, + rsu_dcmf_status_callback); if (ret) { dev_err(dev, "Error, getting DCMF status %i\n", ret); - stratix10_svc_free_channel(priv->chan); + goto remove_async_client; } =20 ret =3D rsu_send_msg(priv, COMMAND_RSU_MAX_RETRY, 0, rsu_max_retry_callback); if (ret) { dev_err(dev, "Error, getting RSU max retry %i\n", ret); - stratix10_svc_free_channel(priv->chan); + goto remove_async_client; } =20 - ret =3D rsu_send_async_msg(dev, priv, COMMAND_RSU_GET_SPT_TABLE, 0, rsu_async_get_spt_table_callback); if (ret) { dev_err(dev, "Error, getting SPT table %i\n", ret); - stratix10_svc_free_channel(priv->chan); + goto remove_async_client; } =20 + return 0; + +remove_async_client: + stratix10_svc_remove_async_client(priv->chan); +free_channel: + stratix10_svc_free_channel(priv->chan); return ret; } =20 --=20 2.42.0.411.g813d9a9188