From nobody Mon Jun 8 08:35:25 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 6E00134D389 for ; Sat, 30 May 2026 20:45:39 +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=1780173940; cv=none; b=hYgK1rp6Tk3rfX5hvGDV5BSSvTl6/lO7c8Vxxyd3tOeez/qSRj6IlgTdH+XXHFkhEoW73LKavpKGLS60gXHH5/BUBCx9mw8I7mcnMcKRfrk+omkJvv6tva1qYEXJvSbJpG3C0R0CzVRbifNr2gg3xzfVsACi8Bp2+OoXCeSPVRo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780173940; c=relaxed/simple; bh=EeBqujMnkHACF2yaqwSrX9m4yf0spn3iycHA48sOEHY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PWiixfVZozvSJcwhnLgrUsHg70Luy0wYYScgI67a7pvzE1yB4SOHKiTFJElPyRSMlsnCX0ruj6UazvDSIs8NL8xndNtyLMXDLvahcXlxUPS56S/NBF+VXbxtP0X3gnZ0xBWwDHyO/UjvEwBdLcYdSngAm8egsMmi6D4a8x3dCnc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mIAGx1gM; 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="mIAGx1gM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B53C1F0089A; Sat, 30 May 2026 20:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780173939; bh=HYWr3nvfGAVhk/AFmwS8dqmICjnNqcrf94xAoI7sZPw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mIAGx1gMJWEV3UkRJ9KP06AmblAODZqoXvCjTPS+1FBsff6BBdsnGxnU2QVRKqBgK Sd96TLh6/nsCG/OLuyiclYBcgFQiN0T4ycLCvcbQrS/p4HnzCUXA6su9HSwH6pTmC2 4aNWYTiRXB+afmPrr6N4g0TAAC7PRWCfoBtALgoRDCob6XpotX5ssemgDn+VkeKNze V5NQpfEmDz6tIWNJGo5AR8F2Fk3XXhu2k2cA641msq5SGhQQEYxFbJvgBB1mFo0jyw oZxsfau3uGARShGMhruCXCuYVa29bfb6E4/7avBTEwjqvpxyB9gNfanPiq2Rf1smWN X8m763ELz59KQ== From: srini@kernel.org To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Anandu Krishnan E , stable@kernel.org, Srinivas Kandagatla Subject: [PATCH 1/4] misc: fastrpc: fix use-after-free of fastrpc_user in workqueue context Date: Sat, 30 May 2026 21:45:25 +0100 Message-ID: <20260530204528.116920-2-srini@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530204528.116920-1-srini@kernel.org> References: <20260530204528.116920-1-srini@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Anandu Krishnan E There is a race between fastrpc_device_release() and the workqueue that processes DSP responses. When the user closes the file descriptor, fastrpc_device_release() frees the fastrpc_user structure. Concurrently, an in-flight DSP invocation can complete and fastrpc_rpmsg_callback() schedules context cleanup via schedule_work(&ctx->put_work). If the workqueue runs fastrpc_context_free() in parallel with or after fastrpc_device_release() has freed the user structure, it dereferences the freed fastrpc_user. Depending on the state of the context at the time of the race, any one of the following accesses can be hit: 1. fastrpc_buf_free() calls fastrpc_ipa_to_dma_addr(buf->fl->cctx, ...) to strip the SID bits from the stored IOVA before passing the physical address to dma_free_coherent(). 2. fastrpc_free_map() reads map->fl->cctx->vmperms[0].vmid to reconstruct the source permission bitmask needed for the qcom_scm_assign_mem() call that returns memory from the DSP VM back to HLOS. 3. fastrpc_free_map() acquires map->fl->lock to safely remove the map node from the fl->maps list. The resulting use-after-free manifests as: pc : fastrpc_buf_free+0x38/0x80 [fastrpc] lr : fastrpc_context_free+0xa8/0x1b0 [fastrpc] fastrpc_context_free+0xa8/0x1b0 [fastrpc] fastrpc_context_put_wq+0x78/0xa0 [fastrpc] process_one_work+0x180/0x450 worker_thread+0x26c/0x388 Add kref-based reference counting to fastrpc_user. Have each invoke context take a reference on the user at allocation time and release it when the context is freed. Release the initial reference in fastrpc_device_release() at file close. Move the teardown of the user structure =E2=80=94 freeing pending contexts, maps, mmaps, and the channel context reference =E2=80=94 into the kref release callback fastrpc_user_fre= e(), so that it runs only when the last reference is dropped, regardless of whether that happens at device close or after the final in-flight context completes. Fixes: 6cffd79504ce ("misc: fastrpc: Add support for dmabuf exporter") Cc: stable@kernel.org Signed-off-by: Anandu Krishnan E Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 75 +++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1080f9acf70a..48f8262af539 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -310,6 +310,8 @@ struct fastrpc_user { spinlock_t lock; /* lock for allocations */ struct mutex mutex; + /* Reference count */ + struct kref refcount; }; =20 /* Extract SMMU PA from consolidated IOVA */ @@ -497,15 +499,57 @@ static void fastrpc_channel_ctx_put(struct fastrpc_ch= annel_ctx *cctx) kref_put(&cctx->refcount, fastrpc_channel_ctx_free); } =20 +static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx); + +static void fastrpc_user_free(struct kref *ref) +{ + struct fastrpc_user *fl =3D container_of(ref, struct fastrpc_user, refcou= nt); + struct fastrpc_invoke_ctx *ctx, *n; + struct fastrpc_map *map, *m; + struct fastrpc_buf *buf, *b; + + if (fl->init_mem) + fastrpc_buf_free(fl->init_mem); + + list_for_each_entry_safe(ctx, n, &fl->pending, node) { + list_del(&ctx->node); + fastrpc_context_put(ctx); + } + + list_for_each_entry_safe(map, m, &fl->maps, node) + fastrpc_map_put(map); + + list_for_each_entry_safe(buf, b, &fl->mmaps, node) { + list_del(&buf->node); + fastrpc_buf_free(buf); + } + + fastrpc_channel_ctx_put(fl->cctx); + mutex_destroy(&fl->mutex); + kfree(fl); +} + +static void fastrpc_user_get(struct fastrpc_user *fl) +{ + kref_get(&fl->refcount); +} + +static void fastrpc_user_put(struct fastrpc_user *fl) +{ + kref_put(&fl->refcount, fastrpc_user_free); +} + static void fastrpc_context_free(struct kref *ref) { struct fastrpc_invoke_ctx *ctx; struct fastrpc_channel_ctx *cctx; + struct fastrpc_user *fl; unsigned long flags; int i; =20 ctx =3D container_of(ref, struct fastrpc_invoke_ctx, refcount); cctx =3D ctx->cctx; + fl =3D ctx->fl; =20 for (i =3D 0; i < ctx->nbufs; i++) fastrpc_map_put(ctx->maps[i]); @@ -521,6 +565,8 @@ static void fastrpc_context_free(struct kref *ref) kfree(ctx->olaps); kfree(ctx); =20 + /* Release the reference taken in fastrpc_context_alloc() */ + fastrpc_user_put(fl); fastrpc_channel_ctx_put(cctx); } =20 @@ -628,6 +674,8 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( =20 /* Released in fastrpc_context_put() */ fastrpc_channel_ctx_get(cctx); + /* Take a reference to user, released in fastrpc_context_free() */ + fastrpc_user_get(user); =20 ctx->sc =3D sc; ctx->retval =3D -1; @@ -658,6 +706,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( spin_lock(&user->lock); list_del(&ctx->node); spin_unlock(&user->lock); + fastrpc_user_put(user); fastrpc_channel_ctx_put(cctx); kfree(ctx->maps); kfree(ctx->olaps); @@ -1579,9 +1628,6 @@ static int fastrpc_device_release(struct inode *inode= , struct file *file) { struct fastrpc_user *fl =3D (struct fastrpc_user *)file->private_data; struct fastrpc_channel_ctx *cctx =3D fl->cctx; - struct fastrpc_invoke_ctx *ctx, *n; - struct fastrpc_map *map, *m; - struct fastrpc_buf *buf, *b; unsigned long flags; =20 fastrpc_release_current_dsp_process(fl); @@ -1590,28 +1636,10 @@ static int fastrpc_device_release(struct inode *ino= de, struct file *file) list_del(&fl->user); spin_unlock_irqrestore(&cctx->lock, flags); =20 - if (fl->init_mem) - fastrpc_buf_free(fl->init_mem); - - list_for_each_entry_safe(ctx, n, &fl->pending, node) { - list_del(&ctx->node); - fastrpc_context_put(ctx); - } - - list_for_each_entry_safe(map, m, &fl->maps, node) - fastrpc_map_put(map); - - list_for_each_entry_safe(buf, b, &fl->mmaps, node) { - list_del(&buf->node); - fastrpc_buf_free(buf); - } - fastrpc_session_free(cctx, fl->sctx); - fastrpc_channel_ctx_put(cctx); - - mutex_destroy(&fl->mutex); - kfree(fl); file->private_data =3D NULL; + /* Release the reference taken in fastrpc_device_open */ + fastrpc_user_put(fl); =20 return 0; } @@ -1655,6 +1683,7 @@ static int fastrpc_device_open(struct inode *inode, s= truct file *filp) spin_lock_irqsave(&cctx->lock, flags); list_add_tail(&fl->user, &cctx->users); spin_unlock_irqrestore(&cctx->lock, flags); + kref_init(&fl->refcount); =20 return 0; } --=20 2.53.0 From nobody Mon Jun 8 08:35:25 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 D836B3451A6; Sat, 30 May 2026 20:45:41 +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=1780173942; cv=none; b=DxMxdtRvE+X9TlgCTVTXzI2mA0/BGSySvzDWtjqjvvwcN5+1zCIatJSCoT75M7tcv3oCbzT640bCoHQEkEyPCJDNofzfvUrJmnMb+ATjWubopB22Qgaj6SgfXIiakrRsXlqQSX+TlD1PUUxRLTme+3PYt2+R/BhUTus4EwpTt1I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780173942; c=relaxed/simple; bh=T6E0jSicr1UGCksvCjqzw/G3xzl+VX4dTjLHR0fz7N8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pEdpiYhSDuXTpzoCswvscRe627Wd+Xm/XqJYxSgvIJextJI7ToUtasTCPK+kXuRAWJfx4w0Tf4YPG7rZZUetdytHrUl9iOc2f+QbmeZbW7sURMVeeC+xG5+vIzHmeaX1T482nOZDW130yVfC2FZUcFyeQwKsuzqLfkpYSUH7m+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V0a9960J; 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="V0a9960J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB1A51F00899; Sat, 30 May 2026 20:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780173941; bh=vTvTohLs8KGq8goqLX/0Zg7ELoFsdnFFA2WgJSQgHmU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=V0a9960JEmNR1E2hCrl2h8EjjQ2cExwFbmEZhMpKtcy1kutTYeCevDI+Xfu0qTpMj EK/R/FI7/nWtCq4MXuvuzq09poC2qI+Y5+43u7mlsEpECU3PIKKN3Y6Mjr7I7tD8FG vx7ny/bYEhsg2Rq9A0fSE6a/cutbOGz83LZE6qr5gcxX+b28t0kn2F61guSvG3FbAj wmGrR3NAG9k37ZIuLqDZ/e3oFi576ZUqTAlFDPaOUxfksQC3Swx8K3RRV/GB+Rt7gy okdT/IPyLOxvoH2yMAnyWlaapthtFTq49grCkauN3P/4+YURVWtxS3d5mXVdzfqxkz zlQKkqS5exUuQ== From: srini@kernel.org To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Junrui Luo , stable@vger.kernel.org, Yuhao Jiang , Dmitry Baryshkov , Srinivas Kandagatla Subject: [PATCH 2/4] misc: fastrpc: fix DMA address corruption due to find_vma misuse Date: Sat, 30 May 2026 21:45:26 +0100 Message-ID: <20260530204528.116920-3-srini@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530204528.116920-1-srini@kernel.org> References: <20260530204528.116920-1-srini@kernel.org> 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" From: Junrui Luo fastrpc_get_args() uses find_vma() to look up the VMA for a user-provided pointer and compute a DMA address offset. When the address falls in a gap before the returned VMA, (ptr & PAGE_MASK) - vma->vm_start underflows, corrupting the DMA address sent to the DSP. Replace find_vma() with vma_lookup(), which returns NULL when the address is not contained within any VMA. Cc: stable@vger.kernel.org Fixes: 80f3afd72bd4 ("misc: fastrpc: consider address offset before sending= to DSP") Reported-by: Yuhao Jiang Signed-off-by: Junrui Luo Reviewed-by: Dmitry Baryshkov Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 48f8262af539..cca7489605c5 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1090,7 +1090,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrp= c_invoke_ctx *ctx) pages[i].addr =3D ctx->maps[i]->dma_addr; =20 mmap_read_lock(current->mm); - vma =3D find_vma(current->mm, ctx->args[i].ptr); + vma =3D vma_lookup(current->mm, ctx->args[i].ptr); if (vma) pages[i].addr +=3D (ctx->args[i].ptr & PAGE_MASK) - vma->vm_start; --=20 2.53.0 From nobody Mon Jun 8 08:35:25 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 B7F67352022; Sat, 30 May 2026 20:45:43 +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=1780173944; cv=none; b=aWJyfkymE76/BF9OpzylsFJ+AM2QszsE7Kg0Enkk8kQ4m24xCyKnoaM4Rl89AQbBBNTGmLBfi6aHqKKkyKd+C+161/QJ0ExaclL1uBlIFbiJrs26FXkvXDkomrS8cjKwuLt2Zw/giIXxfDZoBJVhIRnzh7xZu5KuiTvy2dJg7fI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780173944; c=relaxed/simple; bh=09iULX3L/L4V9t85WZL43bXoI4CBZl1LSiLCFd6Qd3I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jvkZ2+2dnSjaj6HFbIBCBhQ+tUe8zfZlZjxtm4L8UdYjma2ur+9I4B3D7KC90lLkOWfRibLpSAIeXc3h45PmxttAfq9dRvsyC/Np58Fux7zj73bu2d+fhgYEjNxuzlPLIzw0V1uXZMp4Ji2xdPXRytm+EtGiinyK0ztLyxevV34= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NZ8C3tFp; 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="NZ8C3tFp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1CD81F0089A; Sat, 30 May 2026 20:45:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780173943; bh=HRxagvXZddwvmbuhDxGbZLEVAk+J9P4idy2x6+WVz8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NZ8C3tFplF6YCq/OCPfKg4sV+MYF6imiRJtMOni2IGjalbF2VwpPYnuQWMBMX5ZbT WykHePyyrfd07xi/c+z7UgbeU8hIxa7CJkF7dTJqQRRon0FaNa1XmNclKkD/sIz5wf T2NzQsLx6Z9TSBYJUVuviwb7rtOHEg1zYXYCbSHq8Fn8DIn6MzAtDwvWLq4zyli/Xs XxCOI5YmDu7YDgQxEjU6sKNYB20moG+xrZDutnBEXwKHKd7hF+R4RiTVLJmAqIObvn i7jbM8dq0M9gWEbAtxYR6r8TcM1Na32ItP/7B2S8XymaOJtYGT7SSxgFpx81HtxN1o IRuOmZJzWTm+w== From: srini@kernel.org To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Mukesh Ojha , stable@vger.kernel.org, Bjorn Andersson , Srinivas Kandagatla Subject: [PATCH 3/4] misc: fastrpc: Fix NULL pointer dereference in rpmsg callback Date: Sat, 30 May 2026 21:45:27 +0100 Message-ID: <20260530204528.116920-4-srini@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530204528.116920-1-srini@kernel.org> References: <20260530204528.116920-1-srini@kernel.org> 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" From: Mukesh Ojha 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 00000= 00000000178 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 mode= l") Cc: stable@vger.kernel.org Signed-off-by: Mukesh Ojha Reviewed-by: Bjorn Andersson Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index cca7489605c5..47cf3d21b51d 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2460,7 +2460,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *r= pdev) =20 kref_init(&data->refcount); =20 - dev_set_drvdata(&rpdev->dev, data); rdev->dma_mask =3D &data->dma_mask; dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); @@ -2469,6 +2468,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *r= pdev) idr_init(&data->ctx_idr); data->domain_id =3D domain_id; data->rpdev =3D rpdev; + dev_set_drvdata(&rpdev->dev, data); =20 err =3D of_platform_populate(rdev->of_node, NULL, NULL, rdev); if (err) @@ -2542,6 +2542,9 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device= *rpdev, void *data, if (len < sizeof(*rsp)) return -EINVAL; =20 + if (!cctx) + return -ENODEV; + ctxid =3D ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); =20 spin_lock_irqsave(&cctx->lock, flags); --=20 2.53.0 From nobody Mon Jun 8 08:35:25 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 96FD2355819; Sat, 30 May 2026 20:45:45 +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=1780173946; cv=none; b=lzqvRYlPuNIxfq/6CCUTboQP4t+gW+nRhYueXooS88UxyI3q6dYeXb985bnqgW9/DbOHBctQIzJMJ6hkMQqfqNdmqG47VvUKnVNjmDeVDSCsxs7Ieca/Jy9ZMZ6bMvs5ebNqBYUo7YBJm/rtiEHTNNIUphS6GEnuaYzOJlZ7wl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780173946; c=relaxed/simple; bh=ivtVcWkO/v1V1f72OYLD+Kr2+OjL1goztC6IflZtIec=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gdXwl5EIa4MxbnS5DIAK6Cg2XmIkF8w7SbI7dAknyIZFlRB8wTi0vtUcbXfnBsJIKLHS62bQ4HQX0bsD/jPoV7F1uk5M5hCAHz5/ktQ+MwNMqNj8DT//+XKtRelB+d31o1HyzF8woY177+3tjtRyXYpd/LDPFoiMgGzG7aL34Mg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nYOSuZWm; 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="nYOSuZWm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E7FDE1F00899; Sat, 30 May 2026 20:45:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780173945; bh=tLisUHuKI53t4eaaqFPc74kLG5u7gVAwhsx0GXoeEZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=nYOSuZWmhUpCeb6hMb+cbFkSs/leMZbl0EuvXMSUfCptHK9KScwImprs98DvXhaVr HbqDhAlqkiC47en1owjn3NI+RALPJRr4z+SZR/Q/VvBj/LBN+hv0xY4ZXPCpUawbee LLDcmMgwgEYB4Zd5Brq2JBBMBUC6a/jk4Ltw+pduYcdJMrRApRlOCcJD7l6524T4p+ RpKLooU1YVTs7l4ohw1aRvlT8ETYMOIKF7KY7s1W59eblp9hu4nkVxv/ugmv3spE9z q0OwGZ3cLFechYELp6+/H4Dcfeh3QSyI6sg5GK7j2CAq4lBtTYeQFRybCdX0+qsiAx Q30jYqTEXWPvA== From: srini@kernel.org To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, Zhenghang Xiao , stable@vger.kernel.org, Srinivas Kandagatla Subject: [PATCH 4/4] misc: fastrpc: fix use-after-free race in fastrpc_map_create Date: Sat, 30 May 2026 21:45:28 +0100 Message-ID: <20260530204528.116920-5-srini@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530204528.116920-1-srini@kernel.org> References: <20260530204528.116920-1-srini@kernel.org> 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" From: Zhenghang Xiao fastrpc_map_lookup returns a raw pointer after releasing fl->lock. The caller fastrpc_map_create then calls fastrpc_map_get (kref_get_unless_zero) on this unprotected pointer. A concurrent MEM_UNMAP can free the map between the lock release and the kref operation, resulting in a use-after-free on the freed slab object. Restore the take_ref parameter to fastrpc_map_lookup so the reference is acquired atomically under fl->lock before the pointer is exposed to the caller. Fixes: 10df039834f8 ("misc: fastrpc: Skip reference for DMA handles") Cc: stable@vger.kernel.org Signed-off-by: Zhenghang Xiao Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 47cf3d21b51d..f3a49384586d 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -388,7 +388,7 @@ static int fastrpc_map_get(struct fastrpc_map *map) =20 =20 static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, - struct fastrpc_map **ppmap) + struct fastrpc_map **ppmap, bool take_ref) { struct fastrpc_map *map =3D NULL; struct dma_buf *buf; @@ -403,6 +403,12 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl,= int fd, if (map->fd !=3D fd || map->buf !=3D buf) continue; =20 + if (take_ref) { + ret =3D fastrpc_map_get(map); + if (ret) + break; + } + *ppmap =3D map; ret =3D 0; break; @@ -920,19 +926,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl= , int fd, static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { - struct fastrpc_session_ctx *sess =3D fl->sctx; - int err =3D 0; - - if (!fastrpc_map_lookup(fl, fd, ppmap)) { - if (!fastrpc_map_get(*ppmap)) - return 0; - dev_dbg(sess->dev, "%s: Failed to get map fd=3D%d\n", - __func__, fd); - } - - err =3D fastrpc_map_attach(fl, fd, len, attr, ppmap); + if (!fastrpc_map_lookup(fl, fd, ppmap, true)) + return 0; =20 - return err; + return fastrpc_map_attach(fl, fd, len, attr, ppmap); } =20 /* @@ -1202,7 +1199,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx= *ctx, for (i =3D 0; i < FASTRPC_MAX_FDLIST; i++) { if (!fdlist[i]) break; - if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap)) + if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false)) fastrpc_map_put(mmap); } =20 --=20 2.53.0