summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMukesh Ojha <mukesh.ojha@oss.qualcomm.com>2026-06-16 18:40:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:38:41 +0200
commita3d91218ccca1e990bfb737b5a6da23f0afba22b (patch)
treee86cc6ebdc3e88eeba32f6b0a6bb05b7a22a28a6
parent5ee32f221713dda4e59eeb95a4a191f5edd413d5 (diff)
downloadlinux-a3d91218ccca1e990bfb737b5a6da23f0afba22b.tar.gz
linux-a3d91218ccca1e990bfb737b5a6da23f0afba22b.zip
misc: fastrpc: Fix NULL pointer dereference in rpmsg callback
[ Upstream commit 5401fb4fe10fac6134c308495df18ed74aebb9c4 ] A NULL pointer dereference was observed on Hawi at boot when the DSP sends a glink message before fastrpc_rpmsg_probe() has completed initialization: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000178 pc : _raw_spin_lock_irqsave+0x34/0x8c lr : fastrpc_rpmsg_callback+0x3c/0xcc [fastrpc] ... Call trace: _raw_spin_lock_irqsave+0x34/0x8c (P) fastrpc_rpmsg_callback+0x3c/0xcc [fastrpc] qcom_glink_native_rx+0x538/0x6a4 qcom_glink_smem_intr+0x14/0x24 [qcom_glink_smem] The faulting address 0x178 corresponds to the lock variable inside struct fastrpc_channel_ctx, confirming that cctx is NULL when fastrpc_rpmsg_callback() attempts to take the spinlock. There are two issues here. First, dev_set_drvdata() is called before spin_lock_init() and idr_init(), leaving a window where the callback can retrieve a valid cctx pointer but operate on an uninitialized spinlock. Second, the rpmsg channel becomes live as soon as the driver is bound, so fastrpc_rpmsg_callback() can fire before dev_set_drvdata() is called at all, resulting in dev_get_drvdata() returning NULL. Fix both issues by moving all cctx initialization ahead of dev_set_drvdata() so the structure is fully initialized before it becomes visible to the callback, and add a NULL check in fastrpc_rpmsg_callback() as a guard against any remaining window. Fixes: f6f9279f2bf0 ("misc: fastrpc: Add Qualcomm fastrpc basic driver model") Cc: stable@vger.kernel.org Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Reviewed-by: Bjorn Andersson <andersson@kernel.org> Signed-off-by: Srinivas Kandagatla <srini@kernel.org> Link: https://patch.msgid.link/20260530204528.116920-4-srini@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/fastrpc.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 3ba0b322adb2..f0d12fe34b85 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1689,7 +1689,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
kref_init(&data->refcount);
- dev_set_drvdata(&rpdev->dev, data);
rdev->dma_mask = &data->dma_mask;
dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
INIT_LIST_HEAD(&data->users);
@@ -1697,6 +1696,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
idr_init(&data->ctx_idr);
data->domain_id = domain_id;
data->rpdev = rpdev;
+ dev_set_drvdata(&rpdev->dev, data);
return of_platform_populate(rdev->of_node, NULL, NULL, rdev);
}
@@ -1744,6 +1744,9 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
if (len < sizeof(*rsp))
return -EINVAL;
+ if (!cctx)
+ return -ENODEV;
+
ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
spin_lock_irqsave(&cctx->lock, flags);