From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 009382222D9 for ; Tue, 30 Jun 2026 06:34:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782801260; cv=none; b=AbpJY5/kCreNuGfrt3ZuEJHNPQke+Iz8hsFnRxyLdGAThtZo/7tbZBhbDn3hz4grfH4aOh7YnMxdroQdAihadycXngpnrSbrXolsxjtAvRl+moigw1cIua2ml132zkzoUQ6nCpzcKUij2TyFJuNX2lbmJXHzvQ1GDysKDHxgO84= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782801260; c=relaxed/simple; bh=0EL6ZU1jr7FjV/0QKknVsKrIBbWfjMwe1MCkyMpTnRM=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=fOKA9JZetGn3EdVqAOBHJ6pw21HLa+gyvyTYkt1UkyIzLyXR+d2pit3c7n0IIi7iLzsL3p+zsq1FMagILXfNMcInlPQop0A46IXuYXalRCwm3azgfmB/oVTGe2DKxTAtMNICNPFfY0Gr4HpSNKFdpgWIurOYLbS+jHViE1V3MLU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=PmKdbvoY; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=LJVCOSpD; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="PmKdbvoY"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="LJVCOSpD" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65U6CLIS1087220 for ; Tue, 30 Jun 2026 06:34:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:message-id:mime-version :subject:to; s=qcppdkim1; bh=Lkk1aid6VSjCiAh0RBtC69AWGsaj2zmcu8D ZktAdjhA=; b=PmKdbvoYoQGt6wie3aKrjDVrvI47ima6lzT04Aznd9GbfdlaeF4 wbLUBZVHd3yuMJbkZ2XdOvgeTkpbMCoZJ3lo6xkj30XLC9CvHNOaWm5Qhfwmd90D S9oztBzB4PT15/qpxqn7NFoiQuolBcy+sUBCk/GxxbMhVLCwwDHRi5XSCeeZdMUE mU66hWnt77zqT6n58ZgUIEQAqrC0bOkr+4LW0jamt2QeTcztvhU5y7AGsoV+7CpT c5gjKIZ+Z5Wr7zAWJrT6SYYd3JykFRXRWA+gNelZiu3YbydjZUzK2sOTMybEzFY8 GrMGwQLKDtC9xxnTHMnjwKfYRoi8OT0oHSQ== Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4f3qhac6xv-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 30 Jun 2026 06:34:17 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2c80be91ea3so62981705ad.1 for ; Mon, 29 Jun 2026 23:34:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1782801257; x=1783406057; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Lkk1aid6VSjCiAh0RBtC69AWGsaj2zmcu8DZktAdjhA=; b=LJVCOSpDAjgZGX4+VV0nub/3zoBH0ac1gbKESQkrnKAjuncNmBWFqPrzcMwI6nFFnK 4YjqYDa91fIJZZnSmczPS/cbt4FMXkGCUekjecJu4x0RVvIH+SlGNufe1r4OMH0aJcp7 NDFYu5Bvvaf1aT1miQbiTu6F0QalhS9vTiVZH6sg1iaIaN0j8elR8gR1/ra8uk8IP7U/ Bv5EciVIu2TMqDjWPIHmYvIQU31NsFDKrTKtHrB9hsWLg66xGJ16yilCTkoiiv6zaTOq s/7i1NoyGPa7OHGW2j0cIrltuK4Idljj9w2AoWVi8Gq+ZsFsxdVEW9McnzUOXI5Ke75B 8YzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782801257; x=1783406057; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Lkk1aid6VSjCiAh0RBtC69AWGsaj2zmcu8DZktAdjhA=; b=dNvVoLtu2JSp0kdWRl9c5w/+fDYH11wry8ANKYxRdCUCNLBMoqodTOlIvGpwVZwoiV 9WtwmtclRPY+A72Hgwh3H/uwwoifFoB29Vqr9R6ATZsonDVma6YtirXZnakpNS/IOOLk ih9M1wN4jWiduER+iH0TvXqu4TfLhyuQKHvLBv1hNmGnA0cuheDjERqkAYvAaNrBA+sv jjwF8NczwIiTfSCpmYq479+MpMDoNzYecLKda2/kBga+jzoMPhDQU2iUBHcSJqUFmoAA FCZEVGRmjMhXcL/H2lfa9eOxvEJokqS+YwrSDUV2RmPVR2UasR5ZcJwf0ywPIdg6l5C0 dQdw== X-Forwarded-Encrypted: i=1; AHgh+RrnSKw9Or6+5BW4azlLIAR8/1ZQUkMdm4SAHrZ2wJOm1MG+DvTgFEbR8w92u9l4AhVZ/mkFt38ASQS7VLk=@vger.kernel.org X-Gm-Message-State: AOJu0YzL+y+DzZ6Ym/diTQaWczZiWlxEcYRWPxmI0oQ80dmw1JXFIbuj 27nSaJD/YtvhhxysKF/y++zq/g/+kWVjuKqC4K0s0YOv/gf/dCnTQUcpsIFhlySFbjv0wG+5nAY MCRgWS1tklf8ia7C2El2mBKsqWg//0KIxQz3fobE2ejP9FEYZ7eqywfmNlLherW1WG+Y= X-Gm-Gg: AfdE7cmYWHnojkbzbbVP3IZr6JrXLqq2c2Z17O5LVmWhNcLH72UNEdXVGvqoVWD3hVS 9Qk8/t52vMlFlBf02zu6RaLpPQeTqgB7rDpFypy95HtSNFFYCb9zTnZdzFntF031QkzEdbX/FoM 92kobbLdD7sq6FsnpjEeJS/fEcTgR185Z6Xckr9Y4Og7723OvKbKCzR0gr6jhMVfMuZvTSR0lxc 47yQJLCsv78/pI8oxaJMsKclfswT9Df5qOk1o3UtBy+OOZ9icc1c61yQOY66XQDsyoPUP6/9VVp ghZx5VNO6xi1rLGXGIAKZDSSVBalNtffHP+CJqY2vQgLOf6ortklPk9H1cVuh7YkFBuupX5jzHe 1kGSbaMamkyzepFmj2aeluvGjR71yqOvJHHnMs53NmakUUjJ01Eu6vp6JKa9A7/+AMoCe7jqNSY xRGtSWwzs= X-Received: by 2002:a17:903:4b2f:b0:2ca:11fd:659d with SMTP id d9443c01a7336-2ca2ea238ccmr19680525ad.34.1782801256820; Mon, 29 Jun 2026 23:34:16 -0700 (PDT) X-Received: by 2002:a17:903:4b2f:b0:2ca:11fd:659d with SMTP id d9443c01a7336-2ca2ea238ccmr19680235ad.34.1782801256193; Mon, 29 Jun 2026 23:34:16 -0700 (PDT) Received: from QCOM-SocCW5bzXR.qualcomm.com (tpe-colo-wan-fw-bordernet.qualcomm.com. [103.229.16.4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ca382d0d22sm6646345ad.80.2026.06.29.23.34.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jun 2026 23:34:15 -0700 (PDT) From: Jianping Li To: Srinivas Kandagatla , Amol Maheshwari Cc: Jianping Li , Arnd Bergmann , Greg Kroah-Hartman , Thierry Escande , Ekansh Gupta , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, quic_chennak@quicinc.com, stable@kernel.org Subject: [PATCH v2] misc: fastrpc: fix UAF and kernel panic during cleanup on process abort Date: Tue, 30 Jun 2026 14:34:09 +0800 Message-Id: <20260630063409.475-1-jianping.li@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Proofpoint-GUID: ifbYAlvydRGRCMH8FF1qKDwj7z4hMX0u X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjMwMDA1NCBTYWx0ZWRfX5zV0fU3wvso0 dEwEGYRKp0iqXBgLEw5DcKznXUTANirkW3fxzxuAgNB8q5/loVqVKnkXIqyWyIDjmrgBSyPDeyq 6VN6cDa68quwnQHay6+4qXbtqMma+d8NWq3qA2Qar9zpQLLPe6QF4Z1yjaPS+p5iFW/bjbHSzfu TGQNy6P/pKWT8ngsBjlKeXa2BG9LP5Hkkps2UpL7VQK97SdxvTS4DVTGPshencHhjIdjqOrrXV0 0vRKZA1Blzs5f9Z3wkQOqZhfQVJRbZYiBcmLZD1A6tXHVPB0WDIorBArwNXbHNxvYRxUqCUut7y 3Wqi23EgEE6NvG9BczcyG66e+koOYsRV6QTKHWbREvsj+RxvW3cK7fe6ZZ6snJY46Yg0BRY0lz6 +CwTfLLjI6CKX8DtL8twPw/GgjFtsOjVxYrt1I1pb+iiINUZw4yMGgZ4aHN1s6LuMdEfkEywRC7 f+NyA/kBv8OMzr1w+cA== X-Proofpoint-Spam-Info: AW1haW4tMjYwNjMwMDA1NCBTYWx0ZWRfX3zAGyLZyNaJ7 U+oBaEtRkexILo1lpycwwviRp8ku63VYpV1mVvejLpUE7kM1MlPuF1PwjzFGyoLjXWHczbQQHda zS1vhqB5+ezvDN2clAqLtRcUcJsSzX4= X-Authority-Analysis: v=2.4 cv=O9UJeh9W c=1 sm=1 tr=0 ts=6a436369 cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=nuhDOHQX5FNHPW3J6Bj6AA==:17 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=7UBpWWJXUKeOLZOJV8wA:9 a=GvdueXVYPmCkWapjIL-Q:22 X-Proofpoint-ORIG-GUID: ifbYAlvydRGRCMH8FF1qKDwj7z4hMX0u X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-30_02,2026-06-26_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 adultscore=0 impostorscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 priorityscore=1501 clxscore=1015 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606300054 When a userspace FastRPC client is abruptly terminated, FastRPC cleanup paths can race with device and session teardown. This results in kernel panics in different release paths: - fastrpc_release() when using remote heap, originating from fastrpc_buf_free() - fastrpc_device_release() when using system heap, originating from fastrpc_free_map() In addition, fastrpc_map_put() may trigger refcount use-after-free due to concurrent cleanup without proper synchronization. The root cause is that buffer and map cleanup paths may access map and buf resources after the associated device or session has already been released. Fix this by: - Introducing mutex protection for map and buf lifetime - Serializing buffer and map cleanup against device teardown - Skipping buffer and map operations when the device is already gone These changes ensure cleanup paths are safe against unexpected process aborts and prevent use-after-free and kernel panic scenarios. Fixes: c68cfb718c8f9 ("misc: fastrpc: Add support for context Invoke method") Cc: stable@kernel.org Signed-off-by: Jianping Li --- drivers/misc/fastrpc.c | 57 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index a9b2ae44c06f..3521518f9fe5 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -255,6 +255,8 @@ struct fastrpc_session_ctx { int sid; bool used; bool valid; + bool allocated; + struct mutex mutex; }; struct fastrpc_soc_data { @@ -335,9 +337,14 @@ static inline u64 fastrpc_sid_offset(struct fastrpc_channel_ctx *cctx, static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; + struct fastrpc_user *fl; map = container_of(ref, struct fastrpc_map, refcount); + fl = map->fl; + if (!fl) + return; + if (map->table) { if (map->attr & FASTRPC_ATTR_SECUREMAP) { struct qcom_scm_vmperm perm; @@ -356,10 +363,16 @@ static void fastrpc_free_map(struct kref *ref) return; } } + mutex_lock(&fl->sctx->mutex); + if (!fl->sctx->dev) { + mutex_unlock(&fl->sctx->mutex); + return; + } dma_buf_unmap_attachment_unlocked(map->attach, map->table, DMA_BIDIRECTIONAL); dma_buf_detach(map->buf, map->attach); dma_buf_put(map->buf); + mutex_unlock(&fl->sctx->mutex); } if (map->fl) { @@ -422,9 +435,18 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, static void fastrpc_buf_free(struct fastrpc_buf *buf) { - dma_free_coherent(buf->dev, buf->size, buf->virt, - fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr)); - kfree(buf); + struct fastrpc_user *fl = buf->fl; + + if (!fl) + return; + mutex_lock(&fl->sctx->mutex); + if (fl->sctx->dev) { + dma_free_coherent(buf->dev, buf->size, buf->virt, + fastrpc_ipa_to_dma_addr(buf->fl->cctx, + buf->dma_addr)); + kfree(buf); + } + mutex_unlock(&fl->sctx->mutex); } static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, @@ -447,8 +469,11 @@ static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf->dev = dev; buf->raddr = 0; - buf->virt = dma_alloc_coherent(dev, buf->size, &buf->dma_addr, - GFP_KERNEL); + mutex_lock(&fl->sctx->mutex); + if (fl->sctx->dev) + buf->virt = dma_alloc_coherent(dev, buf->size, &buf->dma_addr, + GFP_KERNEL); + mutex_unlock(&fl->sctx->mutex); if (!buf->virt) { mutex_destroy(&buf->lock); kfree(buf); @@ -491,6 +516,10 @@ static void fastrpc_channel_ctx_free(struct kref *ref) struct fastrpc_channel_ctx *cctx; cctx = container_of(ref, struct fastrpc_channel_ctx, refcount); + for (int i = 0; i < FASTRPC_MAX_SESSIONS; i++) { + if (cctx->session[i].allocated) + mutex_destroy(&cctx->session[i].mutex); + } kfree(cctx); } @@ -855,19 +884,28 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, goto get_err; } + mutex_lock(&fl->sctx->mutex); + if (!fl->sctx->dev) { + err = -ENODEV; + mutex_unlock(&fl->sctx->mutex); + goto attach_err; + } map->attach = dma_buf_attach(map->buf, sess->dev); if (IS_ERR(map->attach)) { dev_err(sess->dev, "Failed to attach dmabuf\n"); err = PTR_ERR(map->attach); + mutex_unlock(&fl->sctx->mutex); goto attach_err; } table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); if (IS_ERR(table)) { err = PTR_ERR(table); + mutex_unlock(&fl->sctx->mutex); goto map_err; } map->table = table; + mutex_unlock(&fl->sctx->mutex); if (attr & FASTRPC_ATTR_SECUREMAP) map->dma_addr = sg_phys(map->table->sgl); @@ -2246,6 +2284,8 @@ static int fastrpc_cb_probe(struct platform_device *pdev) sess->used = false; sess->valid = true; sess->dev = dev; + mutex_init(&sess->mutex); + sess->allocated = true; dev_set_drvdata(dev, sess); sess->sid = sid; @@ -2260,6 +2300,8 @@ static int fastrpc_cb_probe(struct platform_device *pdev) break; dup_sess = &cctx->session[cctx->sesscount++]; memcpy(dup_sess, sess, sizeof(*dup_sess)); + mutex_init(&dup_sess->mutex); + dup_sess->allocated = true; } } spin_unlock_irqrestore(&cctx->lock, flags); @@ -2282,6 +2324,11 @@ static void fastrpc_cb_remove(struct platform_device *pdev) spin_lock_irqsave(&cctx->lock, flags); for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) { if (cctx->session[i].sid == sess->sid) { + spin_unlock_irqrestore(&cctx->lock, flags); + mutex_lock(&cctx->session[i].mutex); + cctx->session[i].dev = NULL; + mutex_unlock(&cctx->session[i].mutex); + spin_lock_irqsave(&cctx->lock, flags); cctx->session[i].valid = false; cctx->sesscount--; } -- 2.43.0