[PATCH v2 01/22] powerpc/spufs: don't dump more than the note supports
From: Christian Brauner
Date: Wed Aug 19 2026 - 19:10:55 EST
The spufs_arch_write_note() function puts notes in the header and uses
them to fin where the next note starts. The spufs_coredump_read[] array
provides the sizes of the notes:
dump_skip_to(cprm, roundup(cprm->pos - ret + sz, 4));
In this call @ret is the amount of data the dump callback wrote. @sz is
the declared size. So the position moves backwards if the callback
wrote more data than the declared size.
For three note sizes that is the case:
(1) signal1 sets sizeof(u32) and dumps u64 via sizeof(ctx->csa.spu_chnldata_RW[3])
(2) signal2 sets sizeof(u32) and dumps u64 via sizeof(ctx->csa.spu_chnldata_RW[4])
(3) ibox_info sets sizeof(u32) and dumps a u64 via puint_mb_R
The note is 4 byte aligned. The dump_emit() call wrote the dump_align(4)
just before the note. So if @ret is 8 and @sz is 4 the position ends up
4 bytes before the current position which means cprm->to_skip is now
negative.
For __dump_skip() with size_t that means the pipe or socket gets 2^52
PAGE_SIZE zeroes. This also means a file seeks backwards and overwrites
the four bytes that it just wrote.
Before commit 5456ffdee666 ("powerpc/spufs: simplify spufs core
dumping") this was benign because this truncated (on purpose, I
presume):
u32 data;
data = ctx->csa.spu_chnldata_RW[3];
...
copy_to_user(buf, &data, 4)
and after said commit things became fscked. So let's truncate this
again. Not truncation means the wrong bits will be picked on big endian.
Afaict, spufs is effectively dead so the fix probably doesn't matter in
the grand scheme of things.
Fixes: 5456ffdee666 ("powerpc/spufs: simplify spufs core dumping")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
arch/powerpc/platforms/cell/spufs/file.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index de7494748fec..6f86d87e3749 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -956,10 +956,12 @@ spufs_signal1_release(struct inode *inode, struct file *file)
static ssize_t spufs_signal1_dump(struct spu_context *ctx,
struct coredump_params *cprm)
{
+ u32 data;
+
if (!ctx->csa.spu_chnlcnt_RW[3])
return 0;
- return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[3],
- sizeof(ctx->csa.spu_chnldata_RW[3]));
+ data = ctx->csa.spu_chnldata_RW[3];
+ return spufs_dump_emit(cprm, &data, sizeof(data));
}
static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf,
@@ -1089,10 +1091,12 @@ spufs_signal2_release(struct inode *inode, struct file *file)
static ssize_t spufs_signal2_dump(struct spu_context *ctx,
struct coredump_params *cprm)
{
+ u32 data;
+
if (!ctx->csa.spu_chnlcnt_RW[4])
return 0;
- return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[4],
- sizeof(ctx->csa.spu_chnldata_RW[4]));
+ data = ctx->csa.spu_chnldata_RW[4];
+ return spufs_dump_emit(cprm, &data, sizeof(data));
}
static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf,
@@ -1965,10 +1969,12 @@ static const struct file_operations spufs_mbox_info_fops = {
static ssize_t spufs_ibox_info_dump(struct spu_context *ctx,
struct coredump_params *cprm)
{
+ u32 data;
+
if (!(ctx->csa.prob.mb_stat_R & 0xff0000))
return 0;
- return spufs_dump_emit(cprm, &ctx->csa.priv2.puint_mb_R,
- sizeof(ctx->csa.priv2.puint_mb_R));
+ data = ctx->csa.priv2.puint_mb_R;
+ return spufs_dump_emit(cprm, &data, sizeof(data));
}
static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
--
2.53.0