[PATCH 2/3] powerpc/spufs: fix type confusion in cntl mmap fault handler

Zhenhao Wan <[email protected]>
Newsgroups gmane.linux.ports.ppc.embedded
Message-ID <20260814-spufs-groupa-v1-2-f38f7549ce20__35369.5984509372$1786721560$gmane$org@gmail.com>
spufs_ps_fault() recovers the SPU context from the faulting file with

	struct spu_context *ctx = vmf->vma->vm_file->private_data;

This is correct for most spufs files, whose ->open stores the context in
file->private_data. The cntl file is the exception: spufs_cntl_open()
sets file->private_data = ctx but then calls simple_attr_open(), which
allocates a struct simple_attr and overwrites file->private_data with it
so that simple_attr_read()/write() work. cntl is also the only such file
that installs an mmap fault handler (spufs_cntl_mmap, on 4K-page
configs). When that mapping is faulted, spufs_ps_fault() reads back the
struct simple_attr as a struct spu_context and dereferences it
(ctx->state, ctx->spu->problem_phys), feeding a bogus value into
vmf_insert_pfn() -- a type confusion reachable by an unprivileged opener
of the 0666 cntl file.

Obtain the context from the inode instead, which always refers to the
real spu_context regardless of what ->private_data holds, matching how
coredump_next_context() and the affinity path already fetch it. This is
equivalent for every other spufs_ps_fault() caller and removes cntl's
dependence on a pointer that simple_attr_open() owns.

Fixes: e1dbff2bafa8 ("[POWERPC] spufs: add support for read/write on cntl")
Reported-by: Yuhao Jiang <[email protected]>
Assisted-by: Claude:claude-opus-5
Cc: [email protected]
Signed-off-by: Zhenhao Wan <[email protected]>
---
 arch/powerpc/platforms/cell/spufs/file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index de7494748fec..8c7515140efb 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -313,7 +313,7 @@ static vm_fault_t spufs_ps_fault(struct vm_fault *vmf,
 				    unsigned long ps_offs,
 				    unsigned long ps_size)
 {
-	struct spu_context *ctx = vmf->vma->vm_file->private_data;
+	struct spu_context *ctx = SPUFS_I(file_inode(vmf->vma->vm_file))->i_ctx;
 	unsigned long area, offset = vmf->pgoff << PAGE_SHIFT;
 	int err = 0;
 	vm_fault_t ret = VM_FAULT_NOPAGE;

-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.