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