* [PATCH 1/5] mm: do not call vm_ops->access with FOLL_ANON
2026-11-12 22:08 [PATCH 0/5] mm,drm/i915,powerpc/spufs: vm_ops->access related fixes David Hildenbrand (Arm)
@ 2026-11-12 22:08 ` David Hildenbrand (Arm)
2026-11-12 22:08 ` [PATCH 2/5] drm/i915: consider vm_pgoff in vm_access() David Hildenbrand (Arm)
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-12 22:08 UTC (permalink / raw)
To: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
David Hildenbrand (Arm),
Chris Mason, stable
From: Chris Mason <mason@kernel.org>
Reading /proc/<pid>/cmdline or /proc/<pid>/environ can block in a device
driver, or read device memory, if the virtual addresses point at a device
mapping.
Ever since commit 7f7ccc2ccc2e ("proc: do not access cmdline nor environ
from file-backed areas") we use FOLL_ANON to only read from anonymous
memory. While GUP properly handles FOLL_ANON, __access_remote_vm()
will fall back on GUP errors to vma->vm_ops->access() without similarly
considering the flag.
Fix it by not calling vm_ops->access if FOLL_ANON was specified, to
truly limit it to anonymous memory only.
Fixes: 7f7ccc2ccc2e ("proc: do not access cmdline nor environ from file-backed areas")
Signed-off-by: Chris Mason <mason@kernel.org>
Cc: stable@vger.kernel.org
[ david: simplify description; slightly rework implementation ]
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
mm/memory.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/memory.c b/mm/memory.c
index 1a0ec09c56fd7..d4370c1b331c9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -7398,6 +7398,9 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
continue;
}
+ if (gup_flags & FOLL_ANON)
+ break;
+
/*
* Check if this is a VM_IO | VM_PFNMAP VMA, which
* we can access using slightly different code.
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 2/5] drm/i915: consider vm_pgoff in vm_access()
2026-11-12 22:08 [PATCH 0/5] mm,drm/i915,powerpc/spufs: vm_ops->access related fixes David Hildenbrand (Arm)
2026-11-12 22:08 ` [PATCH 1/5] mm: do not call vm_ops->access with FOLL_ANON David Hildenbrand (Arm)
@ 2026-11-12 22:08 ` David Hildenbrand (Arm)
2026-11-12 22:08 ` [PATCH 3/5] drm/i915/selftests: request read access for mmap access tests David Hildenbrand (Arm)
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-12 22:08 UTC (permalink / raw)
To: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
David Hildenbrand (Arm),
stable
vm_access() treats the start of every VMA as the beginning of the GEM
object. After a VMA split, vm_pgoff identifies a later part of the
object. Debugger reads and writes through ptrace or /proc/<pid>/mem then
access the wrong bytes.
Properly consider vm_pgoff just like the fault handlers already do.
Fixes: 9f909e215fea ("drm/i915: Implement vm_ops->access for gdb access into mmaps")
Cc: stable@vger.kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
drivers/gpu/drm/i915/gem/i915_gem_mman.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 6b337684dbfe8..e3b24dc8e94f5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -511,13 +511,15 @@ vm_access(struct vm_area_struct *area, unsigned long addr,
struct i915_mmap_offset *mmo = area->vm_private_data;
struct drm_i915_gem_object *obj = mmo->obj;
struct i915_gem_ww_ctx ww;
+ unsigned long obj_offset;
void *vaddr;
int err = 0;
if (i915_gem_object_is_readonly(obj) && write)
return -EACCES;
- addr -= area->vm_start;
+ obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node);
+ addr += (obj_offset << PAGE_SHIFT) - area->vm_start;
if (range_overflows_t(u64, addr, len, obj->base.size))
return -EINVAL;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 3/5] drm/i915/selftests: request read access for mmap access tests
2026-11-12 22:08 [PATCH 0/5] mm,drm/i915,powerpc/spufs: vm_ops->access related fixes David Hildenbrand (Arm)
2026-11-12 22:08 ` [PATCH 1/5] mm: do not call vm_ops->access with FOLL_ANON David Hildenbrand (Arm)
2026-11-12 22:08 ` [PATCH 2/5] drm/i915: consider vm_pgoff in vm_access() David Hildenbrand (Arm)
@ 2026-11-12 22:08 ` David Hildenbrand (Arm)
2026-11-12 22:09 ` [PATCH 4/5] powerpc/spufs: consider vm_pgoff in spufs_mem_mmap_access() David Hildenbrand (Arm)
2026-11-12 22:09 ` [PATCH 5/5] mm: check permissions and bounds for vm_ops->access David Hildenbrand (Arm)
4 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-12 22:08 UTC (permalink / raw)
To: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
David Hildenbrand (Arm)
__igt_mmap_access() reads the buffer with access_process_vm() without
FOLL_FORCE, but creates the mapping with only PROT_WRITE. Request
PROT_READ as well so the test remains valid when we fix the ->access
fallback to properly check VMA access permissions.
Fixes: 9f909e215fea ("drm/i915: Implement vm_ops->access for gdb access into mmaps")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 303be698891fd..d9c828032a1aa 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -1460,7 +1460,8 @@ static int __igt_mmap_access(struct drm_i915_private *i915,
if (err)
return err;
- addr = igt_mmap_offset(i915, offset, obj->base.size, PROT_WRITE, MAP_SHARED);
+ addr = igt_mmap_offset(i915, offset, obj->base.size,
+ PROT_READ | PROT_WRITE, MAP_SHARED);
if (IS_ERR_VALUE(addr))
return addr;
ptr = (unsigned long __user *)addr;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 4/5] powerpc/spufs: consider vm_pgoff in spufs_mem_mmap_access()
2026-11-12 22:08 [PATCH 0/5] mm,drm/i915,powerpc/spufs: vm_ops->access related fixes David Hildenbrand (Arm)
` (2 preceding siblings ...)
2026-11-12 22:08 ` [PATCH 3/5] drm/i915/selftests: request read access for mmap access tests David Hildenbrand (Arm)
@ 2026-11-12 22:09 ` David Hildenbrand (Arm)
2026-11-12 22:09 ` [PATCH 5/5] mm: check permissions and bounds for vm_ops->access David Hildenbrand (Arm)
4 siblings, 0 replies; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-12 22:09 UTC (permalink / raw)
To: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
David Hildenbrand (Arm),
stable
spufs_mem_mmap_access() calculates the local store offset relative to the
start of the VMA and ignores vm_pgoff. After VMA splits, debugger reads and
writes access the wrong part of the local store. Mappings created with a
nonzero file offset have the same problem.
Properly take the vm_pgoff into account, just like spufs_mem_mmap_fault()
already does.
Fixes: a352894d0705 ("spufs: use new vm_ops->access to allow local state access from gdb")
Cc: stable@vger.kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
arch/powerpc/platforms/cell/spufs/file.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 98c47bafaf678..0a46d6f7178ab 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -248,7 +248,8 @@ static int spufs_mem_mmap_access(struct vm_area_struct *vma,
void *buf, int len, int write)
{
struct spu_context *ctx = vma->vm_file->private_data;
- unsigned long offset = address - vma->vm_start;
+ unsigned long offset = address - vma->vm_start +
+ (vma->vm_pgoff << PAGE_SHIFT);
char *local_store;
if (write && !(vma->vm_flags & VM_WRITE))
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 5/5] mm: check permissions and bounds for vm_ops->access
2026-11-12 22:08 [PATCH 0/5] mm,drm/i915,powerpc/spufs: vm_ops->access related fixes David Hildenbrand (Arm)
` (3 preceding siblings ...)
2026-11-12 22:09 ` [PATCH 4/5] powerpc/spufs: consider vm_pgoff in spufs_mem_mmap_access() David Hildenbrand (Arm)
@ 2026-11-12 22:09 ` David Hildenbrand (Arm)
2026-11-13 20:25 ` Kuehling, Felix
4 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-12 22:09 UTC (permalink / raw)
To: Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
David Hildenbrand (Arm),
stable, Felix Kuehling, Christian König, Chris Mason
GUP rejects VM_IO and VM_PFNMAP mappings early. __access_remote_vm() then
falls back to vm_ops->access without checking VMA permissions and without
limiting the request to the VMA size.
Consequently, /proc/<pid>/mem can bypass protections even without
FOLL_FORCE, or cross into another mapping without checking its
permissions.
Check VMA permissions before calling ->access and limit each request to
the current VMA. Implement similar access permission checks as GUP,
however:
(1) Reject writes to CoW mappings because the callbacks access backing
memory directly and cannot handle CoW.
(2) Allow forced writes to non-CoW mappings with VM_MAYWRITE.
This intentionally breaks forced writes through legacy amdgpu PROT_NONE,
MAP_PRIVATE debugger mappings. The workaround in commit fa5239f2af98
("drm/amdgpu: workaround failed COW checks for Thunk VMAs") cleared
VM_MAYWRITE to avoid CoW, but debugger writes still succeeded by
exploiting the missing access-permission checks fixed here. Reads remain
supported. Userspace must use MAP_SHARED instead; ROCm 5.5.0, released
in May 2023, already does so.
Link: https://github.com/ROCm/ROCT-Thunk-Interface/commit/fea44fab6e84eda52fcf6b419b35600c18f4c022
Fixes: 272ddc8b3735 ("proc: don't use FOLL_FORCE for reading cmdline and environment")
Cc: stable@vger.kernel.org
Cc: Felix Kuehling <Felix.Kuehling@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Simona Vetter <simona@ffwll.ch>
Reported-by: Chris Mason <mason@kernel.org>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
mm/memory.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index d4370c1b331c9..9872f289c1e49 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -7362,6 +7362,7 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
void *buf, int len, unsigned int gup_flags)
{
+ const bool force = gup_flags & FOLL_FORCE;
void *old_buf = buf;
int write = gup_flags & FOLL_WRITE;
@@ -7401,15 +7402,35 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
if (gup_flags & FOLL_ANON)
break;
+ if (write) {
+ if (!vma_test(vma, VMA_MAYWRITE_BIT))
+ break;
+ if (!vma_test(vma, VMA_WRITE_BIT) && !force)
+ break;
+ /*
+ * In contrast to GUP, we historically allowed
+ * FOLL_FORCE write access to non-CoW mappings.
+ * However, we must always reject CoW mappings
+ * as we cannot CoW here.
+ */
+ if (vma_is_cow_mapping(vma))
+ break;
+ } else if (!vma_test(vma, VMA_READ_BIT)) {
+ if (!force || !vma_test(vma, VMA_MAYREAD_BIT))
+ break;
+ }
+
/*
* Check if this is a VM_IO | VM_PFNMAP VMA, which
* we can access using slightly different code.
*/
bytes = 0;
#ifdef CONFIG_HAVE_IOREMAP_PROT
- if (vma->vm_ops && vma->vm_ops->access)
+ if (vma->vm_ops && vma->vm_ops->access) {
+ bytes = min_t(unsigned long, len, vma->vm_end - addr);
bytes = vma->vm_ops->access(vma, addr, buf,
- len, write);
+ bytes, write);
+ }
#endif
if (bytes <= 0)
break;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 5/5] mm: check permissions and bounds for vm_ops->access
2026-11-12 22:09 ` [PATCH 5/5] mm: check permissions and bounds for vm_ops->access David Hildenbrand (Arm)
@ 2026-11-13 20:25 ` Kuehling, Felix
0 siblings, 0 replies; 7+ messages in thread
From: Kuehling, Felix @ 2026-11-13 20:25 UTC (permalink / raw)
To: David Hildenbrand (Arm),
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Andrew Morton, Willy Tarreau,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
David Airlie, Simona Vetter, Chris Wilson, Matthew Auld,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Ritesh Harjani (IBM),
Shrikanth Hegde, Rik van Riel, Benjamin Herrenschmidt
Cc: linux-mm, linux-kernel, intel-gfx, dri-devel, linuxppc-dev,
stable, Christian König, Chris Mason
On 2026-11-12 17:09, David Hildenbrand (Arm) wrote:
> GUP rejects VM_IO and VM_PFNMAP mappings early. __access_remote_vm() then
> falls back to vm_ops->access without checking VMA permissions and without
> limiting the request to the VMA size.
>
> Consequently, /proc/<pid>/mem can bypass protections even without
> FOLL_FORCE, or cross into another mapping without checking its
> permissions.
>
> Check VMA permissions before calling ->access and limit each request to
> the current VMA. Implement similar access permission checks as GUP,
> however:
> (1) Reject writes to CoW mappings because the callbacks access backing
> memory directly and cannot handle CoW.
> (2) Allow forced writes to non-CoW mappings with VM_MAYWRITE.
>
> This intentionally breaks forced writes through legacy amdgpu PROT_NONE,
> MAP_PRIVATE debugger mappings. The workaround in commit fa5239f2af98
> ("drm/amdgpu: workaround failed COW checks for Thunk VMAs") cleared
> VM_MAYWRITE to avoid CoW, but debugger writes still succeeded by
> exploiting the missing access-permission checks fixed here. Reads remain
> supported. Userspace must use MAP_SHARED instead; ROCm 5.5.0, released
> in May 2023, already does so.
Thank you for considering this use case and checking the ROCm history.
The patch is
Acked-by: Felix Kuehling <felix.kuehling@amd.com>
>
> Link: https://github.com/ROCm/ROCT-Thunk-Interface/commit/fea44fab6e84eda52fcf6b419b35600c18f4c022
> Fixes: 272ddc8b3735 ("proc: don't use FOLL_FORCE for reading cmdline and environment")
> Cc: stable@vger.kernel.org
> Cc: Felix Kuehling <Felix.Kuehling@amd.com>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Simona Vetter <simona@ffwll.ch>
> Reported-by: Chris Mason <mason@kernel.org>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> ---
> mm/memory.c | 25 +++++++++++++++++++++++--
> 1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index d4370c1b331c9..9872f289c1e49 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -7362,6 +7362,7 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
> static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
> void *buf, int len, unsigned int gup_flags)
> {
> + const bool force = gup_flags & FOLL_FORCE;
> void *old_buf = buf;
> int write = gup_flags & FOLL_WRITE;
>
> @@ -7401,15 +7402,35 @@ static int __access_remote_vm(struct mm_struct *mm, unsigned long addr,
> if (gup_flags & FOLL_ANON)
> break;
>
> + if (write) {
> + if (!vma_test(vma, VMA_MAYWRITE_BIT))
> + break;
> + if (!vma_test(vma, VMA_WRITE_BIT) && !force)
> + break;
> + /*
> + * In contrast to GUP, we historically allowed
> + * FOLL_FORCE write access to non-CoW mappings.
> + * However, we must always reject CoW mappings
> + * as we cannot CoW here.
> + */
> + if (vma_is_cow_mapping(vma))
> + break;
> + } else if (!vma_test(vma, VMA_READ_BIT)) {
> + if (!force || !vma_test(vma, VMA_MAYREAD_BIT))
> + break;
> + }
> +
> /*
> * Check if this is a VM_IO | VM_PFNMAP VMA, which
> * we can access using slightly different code.
> */
> bytes = 0;
> #ifdef CONFIG_HAVE_IOREMAP_PROT
> - if (vma->vm_ops && vma->vm_ops->access)
> + if (vma->vm_ops && vma->vm_ops->access) {
> + bytes = min_t(unsigned long, len, vma->vm_end - addr);
> bytes = vma->vm_ops->access(vma, addr, buf,
> - len, write);
> + bytes, write);
> + }
> #endif
> if (bytes <= 0)
> break;
>
^ permalink raw reply [flat|nested] 7+ messages in thread