From nobody Fri Jun 12 13:56:06 2026 Received: from mail-yx1-f44.google.com (mail-yx1-f44.google.com [74.125.224.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B1363C0607 for ; Thu, 14 May 2026 13:14:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.224.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778764499; cv=none; b=Jn7r/UUD+deRMnX+2PblpLUl1Sg3L73kPu9veAT8bLzwci13dVmMw0WHGE+U5aImAdNBknYTg1Y2R3+b0CqZppmn9i8sQbFn20F+f3PMHA+j/di5GinGIx0ZcWp0SYM6csux2Xf2gzjgLhnvPbwUlTxOKXp4L7lNBvb9/qlzRKo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778764499; c=relaxed/simple; bh=eLQX0hCfqjOFwNZCA/EHeNEE+ENmXxZphH84nqdSkS8=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ktkPooRczmuN3sXrN1ZrK1NO6yX2SR2rZl8uTsRmgFwOfbakdITL5AgQ2hTvehlqPaS7ITNfyH9nizYewryk/CCd/ucuQ2zGaKlxhawtqz3gB/aOCGOe/24fhBENvKmjpiw/CTIOBrDfpulHPAWtmmFDrHVqpkd93r+URydXVXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=northecho.dev; spf=none smtp.mailfrom=northecho.dev; dkim=pass (2048-bit key) header.d=northecho-dev.20251104.gappssmtp.com header.i=@northecho-dev.20251104.gappssmtp.com header.b=PREF2sNl; arc=none smtp.client-ip=74.125.224.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=northecho.dev Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=northecho.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=northecho-dev.20251104.gappssmtp.com header.i=@northecho-dev.20251104.gappssmtp.com header.b="PREF2sNl" Received: by mail-yx1-f44.google.com with SMTP id 956f58d0204a3-65c20ffb440so1177049d50.1 for ; Thu, 14 May 2026 06:14:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=northecho-dev.20251104.gappssmtp.com; s=20251104; t=1778764497; x=1779369297; 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=29KtfuJlXrDbhr12CTsDbe7NtrYpv9Xo28OIJR4h52E=; b=PREF2sNl90JvxY7ot1fu/4bXSXrtDixKBS0xvTbfPA6UHYTIhO4y2PFTMBiAWRzuj/ uSlsM/H2fEoXUj/npJ5gaT4LkugM5bIm/SpS2rvedUz+L2ut4WOBs8iVUY+Jd5tOLcRD 9gDKQlo+cO3U+GDHPicp2gZd2/zg2kHMLXEMOt2YtBnOBM26+mz3o8gJdPjBkDRR5OYS m1FUwCtzrJ1fGBF+4tESAxsydoCOi76ZOjcS6d8ZPwLwemrXZ6v6hzhXJXJj85hQIl9n KZbBjo2+tnXQF7V3ww/PR5Kbb8LXvIndM2YCUhrmtbb5kPlxH7Mmp4L/tPSJdprMTHH3 FFJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778764497; x=1779369297; 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=29KtfuJlXrDbhr12CTsDbe7NtrYpv9Xo28OIJR4h52E=; b=Nnm2f4c5eL5ORCVAEBr+DsWMSuu8ZZX8KOWkOddzsdlGiyaVCS2BEsGk0Dt7EdXqgO yCa7HC4JzP1kMu8wm9t0WCOn5k/LmJLFs1/Ar05C4nIPKW0DSNND4TJ79A5phJqv7arD ohCDr8yBGcOJ9TdnSv8l/X4r+ZMj9pxK7A2rCExGDclapyuJwgXpHMNoass2za4EZRsd X3CNasBJDNn1lO4ItMz7gqpey3Co3mtA1ulILkcv+J460gnaDsTgpXiEgAMcDJaVBxig xBuWyo7yFOtS09JmdFvtZgB1QzgkqO86cHS5XuuxJkRk6oOgh1RDK4SG0qztvFWoWs/m 5vYA== X-Forwarded-Encrypted: i=1; AFNElJ+KTg+B3Szdqm/RFX6ZORx75j9P0GAiMBYdem3ih/s+6MTflE+nTuLVuOS2GmAP4yG/y+0Z0T44tf2/a2Q=@vger.kernel.org X-Gm-Message-State: AOJu0YxOhbw/tJxTUbMPgY1+ULqvsVXlnOpZlkIX8lxfCTy+HusAkzi+ kouYQxQPRMhD14PfuTy7aHdVBxf575UrOB329PMGH/MfA9xDgrdcN9Re6Panvy3ekMIv X-Gm-Gg: Acq92OEtLhOJZj4OtuSMSjTwy9WBj5fASaCuZiuMHRSMq6HMcxd1HpAyGmMDJpLHi5C 3POxzIaN6piO7OCq8hDNKPd1TrsMHRAYrex1QzBhMwOou5Ol5MHCeUM+zIliWOe7KDV4ohorb+0 v3CiK1j3x7WusqbnngBLzWNWb4K1MUQgY320ZPChAKbdIeviTlgwZLzLY3MXwwCo6rIDW8L64QN 8cVfCGD/c4hu51nSXs5Qt6ckkmmJJ/ZAzsNhepwo8WYxGbgzw9ZqVYdAXaGQf5i8SM/HtSMuV3T gutT9mU+QZXACY0MTMEPTrsQcZJu1sZxOpgEFZ3TH+YwPo+lc/6Cqw9vda2fryh9XrqgdvATyS9 yK6qwQFHsfoYFVZP6DSoZirddI2AaXntMQD5VRn6GgdwJQLBtn07z0Tfazj4qlSFsqPdwN4qZoI It4JpvRnMMxd9hcY0a69r0zPL0F+4YlIhQGFagOZ2UoUYCq/a1F2gLER2bPcJMwxfslkiJS1Fz6 CTWbx+p2UdRvQI= X-Received: by 2002:a05:690e:4004:b0:65c:ca50:a6 with SMTP id 956f58d0204a3-65df61e049amr4748006d50.2.1778764497126; Thu, 14 May 2026 06:14:57 -0700 (PDT) Received: from kelso.tail8e61da.ts.net (99-10-92-174.lightspeed.rlghnc.sbcglobal.net. [99.10.92.174]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-65e0db69f26sm1009573d50.17.2026.05.14.06.14.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 May 2026 06:14:55 -0700 (PDT) From: Christopher Lusk To: Lucas Stach Cc: Russell King , Christian Gmeiner , David Airlie , Simona Vetter , etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH] drm/etnaviv: honor read-only userptr flag in GPU MMU mapping Date: Thu, 14 May 2026 09:14:01 -0400 Message-ID: <20260514131401.2660079-1-clusk@northecho.dev> X-Mailer: git-send-email 2.54.0 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" A userptr buffer object created with ETNA_USERPTR_READ (no ETNA_USERPTR_WRITE) is pinned without FOLL_WRITE in etnaviv_gem_userptr_get_pages(); the kernel agrees to allow only read access to the underlying user pages, and the state is recorded as etnaviv_obj->userptr.ro =3D true. etnaviv_iommu_map_gem() then maps the object's sg_table into the GPU MMU with ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE unconditionally, regardless of userptr.ro. A submission that names the BO as a write target therefore causes the GPU to write pages that the kernel pinned without write permission, including page-cache pages of files the caller has only read access to. The ioctl entry points (DRM_ETNAVIV_GEM_NEW_USERPTR, GEM_SUBMIT) are DRM_RENDER_ALLOW, so the path is reachable from any unprivileged render-group user. No intervening permission check, no RO-aware branch, no MMU-level fallback. This is the same class shape as drivers/accel/ivpu commit 7dd57d7a6350 ("accel/ivpu: Disallow re-exporting imported GEM object= s"), fixed 2026-04-30. The Etnaviv manifestation has a simpler trigger path that does not require PRIME re-import. Source-level analysis only - no Vivante hardware was available to validate the mutation primitive end-to-end. Mask ETNAVIV_PROT_WRITE in the call to etnaviv_iommu_map() when the buffer originates as a read-only userptr. The userptr.mm check guards against any non-userptr object that might somehow have userptr.ro set. This work is LLM-assisted: Codex (gpt-5.5) drove the static analysis and class sweep that identified the candidate site; Claude (claude-opus-4-7) drove the writeup and patch refinement. Operator review at each gate. Methodology context at https://northecho.dev/posts/codex-vs-claude-code-vuln-research/. Posted to the public list per the security-bugs.rst exception for findings trivial to discover via automated tooling, as interpreted by the kernel security team for LLM-assisted reports. Signed-off-by: Christopher Lusk Assisted-by: Codex:gpt-5.5 Assisted-by: Claude:claude-opus-4-7 --- v7.1-rc2 reference: drivers/gpu/drm/etnaviv/etnaviv_mmu.c:303-304 Open questions for review: 1. v1 MMU shortcut. etnaviv_iommu_map_gem() takes a shortcut for v1 MMU + single-segment sg_table at lines 278-291, bypassing etnaviv_iommu_map() entirely and using sg_dma_address directly. For typical multi-page userptr BOs sgt->nents > 1 so the shortcut is not taken, but for small contiguous regions on v1 MMU hardware it may apply. This patch does not address the v1 MMU path. If you believe v1 MMU also needs handling, I am happy to follow up with a separate patch. 2. ETNA_SUBMIT_BO_WRITE per-BO flag. etnaviv_gem_submit accepts ETNA_SUBMIT_BO_READ / ETNA_SUBMIT_BO_WRITE per buffer object, currently used for synchronization dependency tracking. Should a submit naming an RO userptr BO with ETNA_SUBMIT_BO_WRITE be rejected at submit time as defense-in-depth? Orthogonal to this patch; happy to follow up with a separate small patch in etnaviv_gem_submit.c if you would like that. 3. Fixes: tag. My v7.1-rc2 clone is shallow; I could not trace the introducing commit for the userptr.ro / ETNA_USERPTR_WRITE distinction. The bug is present in v7.0, v7.1-rc2, and linux-next (2026-05-08). If you have the introducing commit handy from deep Etnaviv history, please add the Fixes: tag in your applied version, or let me know and I will supply it from an unshallowed mirror. A reviewer with Vivante hardware can confirm the primitive with the following pseudocode (before/after this patch): fd =3D open("/dev/dri/renderD128", O_RDWR); ptr =3D mmap(...); /* page-aligned, page-cache-backed file */ bo_handle =3D drm_ioctl(fd, DRM_IOCTL_ETNAVIV_GEM_USERPTR, .ptr =3D ptr, .size =3D page, .flags =3D ETNA_USERPTR_READ); /* GEM_SUBMIT with the BO listed as ETNA_SUBMIT_BO_WRITE and a command stream that writes to the BO GPU VA */ drm_ioctl(fd, DRM_IOCTL_ETNAVIV_GEM_SUBMIT, ...); /* observe: on unpatched kernel, ptr contents have changed; on patched kernel, the write does not land in the user page-cache pages. */ I am happy to source a Vivante board (Sabre Lite, Wandboard, HummingBoard Pro) and post a v2 with Tested-by trailers if you prefer hardware validation before this lands. Source-only is offered first to avoid asking for a hardware-spend decision that may not be necessary. drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnavi= v/etnaviv_mmu.c index e3572461b599..c4dcb7ee3e49 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -301,7 +301,9 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context = *context, =20 mapping->iova =3D node->start; ret =3D etnaviv_iommu_map(context, node->start, etnaviv_obj->size, sgt, - ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE); + (etnaviv_obj->userptr.mm && etnaviv_obj->userptr.ro) ? + ETNAVIV_PROT_READ : + (ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE)); =20 if (ret < 0) { drm_mm_remove_node(node); --=20 2.54.0