From nobody Sat Oct 3 04:28:13 2026 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 827053DAAAF for ; Wed, 5 Aug 2026 06:09:51 +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=1785910193; cv=none; b=jO/MMUOYCPUq2HTQ8SPaeKj2Ho58gltSVffH3wwEbuYWNUxNvi3BgK4dn9UtRMumLMuiDV+PeK9k1+VPVXoOsUiFyEMHYIt01o82ZIAJq24OSqwfqIiBKniF/9Q9g70AQUFZu+jHR4//Z2btl6CMbUs9vEL52MalWka0BOkfvtc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785910193; c=relaxed/simple; bh=K0OUEcgXkxu18FWvcNQyWwFf74F74yYzP0AArcSr2+8=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=KKYCUiZye1WCIB79Dcuvym5R0yiSa6Y3Lw15/wR1MWbOPcQm4SoT4shtgjTFCiP96p9OCEzwz2eRf73f6O7ucVBQlmFCeD6WQZg6r1h3ppzLTWfM/LloA5TPleBAuAH2Y6eOUnJCmxI5O9IOwIO3iTYEvwebrRiSCLtLE2ACYUg= 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=VnLlh5fW; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=H56lDaaC; 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="VnLlh5fW"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="H56lDaaC" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6755lBXU2261089 for ; Wed, 5 Aug 2026 06:09:50 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=8L2Wvo1/28V+1RU6zGe1Oe4JzYrAx0U6d0C N1+O2FKQ=; b=VnLlh5fWgGYL3FbHa73Jtr5ROuQzpJE5disgcDufu2bN1o9akPV iGfe7Hg+KzN/vPiB2Z0FcH0eE0zdNuig+HavjVHKU5rGEifTP2CbZ2rW2qsS+lqr u3iHbgwF6ouabKLtHfh2PDWRYyYZUV1IfhzZbK9h0Ad5XgRD9jTQCwJaGJDcduYY AU8jkgeyiOClAdzLqp171zPT6sCHO0FJkLWgEVpVNARhFHUBO/hPtqtSMcoLm4+R W1kInuxcqx/OnzyAGHQm5C/EHWzxDLADSHizE9wPv5/kxaUgybYzvnd+wAP0uCG0 IYCsL9nTbl8tB5vE3v+EEkx3uclnmcq5feA== Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fug65c78v-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 05 Aug 2026 06:09:50 +0000 (GMT) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-ca7c1e22995so891334a12.3 for ; Tue, 04 Aug 2026 23:09:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1785910189; x=1786514989; 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:content-type; bh=8L2Wvo1/28V+1RU6zGe1Oe4JzYrAx0U6d0CN1+O2FKQ=; b=H56lDaaC0bctCE9Om1QW+osQGTqVjPjfkMvUJU4dp+RJebs4HYImyVCi8jOgiYhm98 bGEhaVDKgFtyH8GWiaMzusA11tNaEcn7ODFsATgZAmWboyBy4KOgAybnooEfADAUN7w3 M3+ioyvmvhuu9QdckDTEwzV0Jq/r0ssUkc+9AZeU4iUObj8lb8NpxE3/L9dZTDqSygMq 7oWsDGPj/N6e8ABj3RPizC35fx5/i+gTliQoo3QpRqCxmpH+UD7rh0WOtCYaPLTOik7D QpOkVVmpibfAvvRMSqFXnM1tX4crGuNBdVrhewhwNbsAsjpzCI6og2VGnj+5l7DsAc1a rDGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785910189; x=1786514989; 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:content-type; bh=8L2Wvo1/28V+1RU6zGe1Oe4JzYrAx0U6d0CN1+O2FKQ=; b=PMPUs2wkX/XNIpMea28vwxwGmwWF7il4gw+Y4g1T9Ye+Rlv297C67g/RZsFRYq2KmB ttvHsCZ+u3GXgmRG8FL4MilsL9TYFUUKAjStMs38OpOjaJRD0C89k2DcGQe9Ni/TbFEm hzK0KXb8res2PsYqNL5Run5LdLeoTe8zR/YXxGVj+9vnAK8XMarEzSod3Q3PM8SpWzAw 7AAgXRLk2SCoAAWYviqJUosDhV1XCoAJ8QfOZh6xjHcnWuuhFBjNsns6w8YNuhEs8Lmw /C+1SQsCmO4Yy1F3TGvwWG+pl+mWwZciMEKcVGOkSMuwI2kS/RCCJfHBeCdnmyOtIZUr EKYA== X-Forwarded-Encrypted: i=1; AHgh+RoStb+p96yWttmqRFZqh7JPIU25itSJ0EUWlXu6PCmj52o+XlQOGIV9hAPfjWvAhvieRlXUvZYdq/vD31k=@vger.kernel.org X-Gm-Message-State: AOJu0YwSOmrKMlXqPstgIz6mje9GgTc4oZFwy71bg3jswKheJr8oMche PBEzgaInP9do1xnIaa0XrvxHvA56AGVOQYCbOX2hwZC1aByvKYxwFe1iKxg73fr6gfFDUEBzRai THqbwf00eWQ83YagXE1+I9ZdQGlauTV3duO1Varnxoqm+M/c28eG67JHiQlRVplyJdoE= X-Gm-Gg: AR+sD11PLKZcSOK9UOZog7KtKB6ZMnYRDT6gHqKHZWr6twd0eYcHmIh6ci2Qk890sGL f22IBOO9zALPZT0o+fVoES4zNPvB3KFaCs9W8ylqQ9ARFyCNziKEbCaGHcKaleN4Q/oQu9xmC3m Td04BZAFgOC3ErYX9HUVDyD+cTDdaWwfvTFsgvFX6EfBizQ57AuTmcNHJgUjpgOAikGzfv2knVk eecowXy6o7IX/fVtEFNIdOrdMoPQjM8IDp9zeYdvY4e7scivqj43cJu1Viz2gB70Bx+xQH5e9bX 6gV30/KTC3P67DZWeAFlyH1aBdwpnun5gfBN7LDNi6WCrFHUCxplFyys0Nd4Laas7+q+za1uwQC UiP3Aq1Dy+M0YSREl6miqdKhjsI8NX6LfCuW4jn7h++3/hf2aAi0BVmYc2Cap6x4hR8FMq9KdKQ == X-Received: by 2002:a05:6a21:a38c:b0:3bf:a681:a262 with SMTP id adf61e73a8af0-3cb8603af5dmr4959754637.38.1785910189091; Tue, 04 Aug 2026 23:09:49 -0700 (PDT) X-Received: by 2002:a05:6a21:a38c:b0:3bf:a681:a262 with SMTP id adf61e73a8af0-3cb8603af5dmr4959702637.38.1785910188598; Tue, 04 Aug 2026 23:09:48 -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 41be03b00d2f7-cbe70909386sm728690a12.28.2026.08.04.23.09.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 23:09:48 -0700 (PDT) From: Jianping Li To: Srinivas Kandagatla , Ekansh Gupta Cc: Jianping Li , Arnd Bergmann , Greg Kroah-Hartman , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Ling Xu , Dmitry Baryshkov , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org, quic_chennak@quicinc.com, stable@kernel.org Subject: [PATCH v3] misc: fastrpc: avoid duplicate DMA mappings in fastrpc_create_maps() Date: Wed, 5 Aug 2026 14:09:40 +0800 Message-Id: <20260805060940.41414-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: quoted-printable X-Proofpoint-ORIG-GUID: CNs7Ygh_ZhvSXpCkzLD9bf7v4uxmcp8n X-Authority-Analysis: v=2.4 cv=fcydDUQF c=1 sm=1 tr=0 ts=6a72d3ae cx=c_pps a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=nuhDOHQX5FNHPW3J6Bj6AA==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=jcsToSEUEPbHcpESBJIA:9 a=x9snwWr2DeNwDh03kgHS:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODA1MDA0NSBTYWx0ZWRfXxdS10rCmW0LW 27epCfiM82mhrQW/OMhkeA8cGRJNBM9uwgniCWDrrcREAyrc+4yJcTWhCSQVj8HY+gyIvszQPD5 rb6NgH/TeUTzN+SMyjuuI1tUxHSFOyI= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA1MDA0NSBTYWx0ZWRfX8CsvC6JUug5q o9dh1AjUNBhsLv6hYAL2z5jNQTtStxmQEw/Vvx3HVFvwHF1P5q21A2+AlFztrYOgPQEWASTySIl wnPpM0NKhT6DVc2MZFhjw6KWf0qtnzfNYPk5nn2pJAXL5MKcPyRd8JKBsJh2fhkuNzFuEqlcjuc FTmFoBJtjHZkBn6onEmn4G7Sfcw1tqL/pvx6BcC7IGPB+bmwdH4K0PmjwW5D3J8PgVS/j68FawB shHUxZ2GwIe7txHe0zOsFT6bfV8nJv4jcNAjt2a4QmAYniEDcDTfbBhYs/uqKL90jycIXEeg/tA 23H2r89N+A35CHG7bMdLJNgiPbwBT6Fow7Pqd31gMqLBjzC5FY3YFpg4M3ggkIryiMl+DzLpQMv BF9SLI0yLO+BQnbpM92WlNmvDOPNW2mqeQcjBmU/8hTCqS2w23emDmok+nG8aGdUjm1UsgaQOqq 9KBgvdB6lzkl2kcZ81A== X-Proofpoint-GUID: CNs7Ygh_ZhvSXpCkzLD9bf7v4uxmcp8n X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-05_02,2026-08-04_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 impostorscore=0 suspectscore=0 adultscore=0 bulkscore=0 clxscore=1015 spamscore=0 priorityscore=1501 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608050045 Content-Type: text/plain; charset="utf-8" DMA handles passed as invoke arguments (scalars beyond nbufs) may refer to the same dma_buf fd as an input/output buffer argument. Taking an extra reference for such DMA handle maps leads to duplicate mappings and an unbalanced reference count, since DMA handle maps are released separately when the DSP returns the fd through the fdlist. Fix this by not taking an extra reference for DMA handle arguments (take_ref =3D false) and tagging them with FASTRPC_MAP_DMA_HANDLE. As these maps are borrowed references, fastrpc_get_args() re-validates the map via fastrpc_map_lookup() before dereferencing it, so it is not used after being freed. fastrpc_put_args() only releases maps flagged as FASTRPC_MAP_DMA_HANDLE and clears the flag to guarantee the map is freed exactly once. Also reject FASTRPC_MAP_DMA_HANDLE in fastrpc_req_mem_map(), since such handles are already mapped implicitly during the remote invoke call and must not be mapped again through the explicit MEM_MAP path. Fixes: 10df039834f84 ("misc: fastrpc: Skip reference for DMA handles") Cc: stable@kernel.org Signed-off-by: Jianping Li Reviewed-by: Ekansh Gupta --- Patch [v2]: https://lore.kernel.org/all/20260716113254.570-1-jianping.li@os= s.qualcomm.com/ Changes in v3: - No functional changes. - fastrpc_put_args(): document that clearing map->flags without a lock is safe because the DSP reports a given fd in the fdlist only once, so no concurrent fastrpc_put_args() can race on the same map's flags. Changes in v2: - Rework the commit message to describe the DMA handle reference and lifetime problem more precisely. - Introduce a new FASTRPC_MAP_DMA_HANDLE uapi flag and a 'flags' field in struct fastrpc_map to explicitly tag DMA handle maps, instead of relying only on the nbufs boundary / take_ref. - Plumb an mflags argument through fastrpc_map_create() and fastrpc_map_attach() so DMA handle maps are tagged at creation time. - Re-validate the borrowed map in fastrpc_get_args() via fastrpc_map_lookup() before dereferencing it, to avoid a use-after-free when the map was created with take_ref =3D false. - In fastrpc_put_args(), only release maps tagged FASTRPC_MAP_DMA_HANDLE and clear the flag afterwards, so such maps are freed exactly once. - Reject FASTRPC_MAP_DMA_HANDLE in fastrpc_req_mem_map(), since these handles are already mapped implicitly during the remote invoke and must not be mapped again through the explicit MEM_MAP path. --- drivers/misc/fastrpc.c | 60 +++++++++++++++++++++++++++---------- include/uapi/misc/fastrpc.h | 2 ++ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 90fd669636ec..8c98c8af6084 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -253,6 +253,7 @@ struct fastrpc_map { u64 len; u64 raddr; u32 attr; + u32 flags; struct kref refcount; }; =20 @@ -879,7 +880,7 @@ static dma_addr_t fastrpc_compute_dma_addr(struct fastr= pc_user *fl, dma_addr_t s } =20 static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, - u64 len, u32 attr, struct fastrpc_map **ppmap) + u64 len, u32 attr, struct fastrpc_map **ppmap, int mflags) { struct fastrpc_session_ctx *sess =3D fl->sctx; struct fastrpc_map *map =3D NULL; @@ -896,6 +897,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, = int fd, =20 map->fl =3D fl; map->fd =3D fd; + map->flags =3D mflags; map->buf =3D dma_buf_get(fd); if (IS_ERR(map->buf)) { err =3D PTR_ERR(map->buf); @@ -970,13 +972,13 @@ static int fastrpc_map_attach(struct fastrpc_user *fl= , int fd, return err; } =20 -static int fastrpc_map_create(struct fastrpc_user *fl, int fd, - u64 len, u32 attr, struct fastrpc_map **ppmap) +static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, u3= 2 attr, + struct fastrpc_map **ppmap, bool take_ref, int mflags) { - if (!fastrpc_map_lookup(fl, fd, ppmap, true)) + if (!fastrpc_map_lookup(fl, fd, ppmap, take_ref)) return 0; =20 - return fastrpc_map_attach(fl, fd, len, attr, ppmap); + return fastrpc_map_attach(fl, fd, len, attr, ppmap, mflags); } =20 /* @@ -1047,23 +1049,25 @@ static int fastrpc_create_maps(struct fastrpc_invok= e_ctx *ctx) int i, err; =20 for (i =3D 0; i < ctx->nscalars; ++i) { + bool take_ref =3D i < ctx->nbufs; + int mflags =3D 0; =20 if (ctx->args[i].fd =3D=3D 0 || ctx->args[i].fd =3D=3D -1 || ctx->args[i].length =3D=3D 0) continue; =20 - if (i < ctx->nbufs) - err =3D fastrpc_map_create(ctx->fl, ctx->args[i].fd, - ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); - else - err =3D fastrpc_map_attach(ctx->fl, ctx->args[i].fd, - ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); + /* Set the DMA handle mapping flag for DMA handles */ + if (i >=3D ctx->nbufs) + mflags =3D FASTRPC_MAP_DMA_HANDLE; + + err =3D fastrpc_map_create(ctx->fl, ctx->args[i].fd, ctx->args[i].length, + ctx->args[i].attr, &ctx->maps[i], take_ref, mflags); if (err) { dev_err(dev, "Error Creating map %d\n", err); return -EINVAL; } - } + return 0; } =20 @@ -1195,6 +1199,16 @@ static int fastrpc_get_args(u32 kernel, struct fastr= pc_invoke_ctx *ctx) list[i].num =3D ctx->args[i].length ? 1 : 0; list[i].pgidx =3D i; if (ctx->maps[i]) { + /* It is possible that map is created with + * mflags FASTRPC_MAP_DMA_HANDLE and take_ref + * is false. Check if map still exists or is + * being freed as take_ref is false + */ + if (fastrpc_map_lookup(ctx->fl, ctx->args[i].fd, + &ctx->maps[i], false)) { + ctx->maps[i] =3D NULL; + return -EINVAL; + } pages[i].addr =3D ctx->maps[i]->dma_addr; pages[i].size =3D ctx->maps[i]->size; } @@ -1244,8 +1258,17 @@ static int fastrpc_put_args(struct fastrpc_invoke_ct= x *ctx, for (i =3D 0; i < FASTRPC_MAX_FDLIST; i++) { if (!fdlist[i]) break; - if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false)) + /* + * DMA handle maps are released when the DSP returns the corresponding f= d in + * fdlist. The DSP is expected to return a specific fd only once in fdli= st, + * so no two fastrpc_put_args() paths should clear the DMA_HANDLE flag f= or + * the same map concurrently. + */ + if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false) && + mmap->flags =3D=3D FASTRPC_MAP_DMA_HANDLE) { + mmap->flags =3D 0; fastrpc_map_put(mmap); + } } =20 return ret; @@ -1621,7 +1644,7 @@ static int fastrpc_init_create_process(struct fastrpc= _user *fl, fl->pd =3D USER_PD; =20 if (init.filelen && init.filefd) { - err =3D fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map); + err =3D fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map, true,= 0); if (err) goto err; } @@ -2246,9 +2269,14 @@ static int fastrpc_req_mem_map(struct fastrpc_user *= fl, char __user *argp) =20 if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; - + /* + * Prevent mapping backward compatible DMA handles here, as they are + * already mapped in the remote call. + */ + if (req.flags =3D=3D FASTRPC_MAP_DMA_HANDLE) + return -EINVAL; /* create SMMU mapping */ - err =3D fastrpc_map_create(fl, req.fd, req.length, 0, &map); + err =3D fastrpc_map_create(fl, req.fd, req.length, 0, &map, true, 0); if (err) { dev_err(dev, "failed to map buffer, fd =3D %d\n", req.fd); return err; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index ba1ea5ed426c..c04749bf4f96 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -45,6 +45,8 @@ enum fastrpc_map_flags { FASTRPC_MAP_FD =3D 2, FASTRPC_MAP_FD_DELAYED, FASTRPC_MAP_FD_NOMAP =3D 16, + /* Map the DMA handle in the invoke call for backward compatibility */ + FASTRPC_MAP_DMA_HANDLE =3D 0x20000, FASTRPC_MAP_MAX, }; =20 --=20 2.43.0