Commit aa0ed2bd authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Arnd Bergmann

[POWERPC] spufs: fix possible memory corruption is spufs_mem_write

Due to a buggy unsigned comparison, it was possible to write
beyond the end of the local store file in spufs under some
circumstances.

This rewrites the buggy function to look more like
simple_copy_from_buffer.
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Cc: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
parent f194bda4
...@@ -63,8 +63,8 @@ static ssize_t ...@@ -63,8 +63,8 @@ static ssize_t
spufs_mem_read(struct file *file, char __user *buffer, spufs_mem_read(struct file *file, char __user *buffer,
size_t size, loff_t *pos) size_t size, loff_t *pos)
{ {
int ret;
struct spu_context *ctx = file->private_data; struct spu_context *ctx = file->private_data;
ssize_t ret;
spu_acquire(ctx); spu_acquire(ctx);
ret = __spufs_mem_read(ctx, buffer, size, pos); ret = __spufs_mem_read(ctx, buffer, size, pos);
...@@ -74,25 +74,29 @@ spufs_mem_read(struct file *file, char __user *buffer, ...@@ -74,25 +74,29 @@ spufs_mem_read(struct file *file, char __user *buffer,
static ssize_t static ssize_t
spufs_mem_write(struct file *file, const char __user *buffer, spufs_mem_write(struct file *file, const char __user *buffer,
size_t size, loff_t *pos) size_t size, loff_t *ppos)
{ {
struct spu_context *ctx = file->private_data; struct spu_context *ctx = file->private_data;
char *local_store; char *local_store;
loff_t pos = *ppos;
int ret; int ret;
size = min_t(ssize_t, LS_SIZE - *pos, size); if (pos < 0)
if (size <= 0) return -EINVAL;
if (pos > LS_SIZE)
return -EFBIG; return -EFBIG;
*pos += size; if (size > LS_SIZE - pos)
size = LS_SIZE - pos;
spu_acquire(ctx); spu_acquire(ctx);
local_store = ctx->ops->get_ls(ctx); local_store = ctx->ops->get_ls(ctx);
ret = copy_from_user(local_store + *pos - size, ret = copy_from_user(local_store + pos, buffer, size);
buffer, size) ? -EFAULT : size;
spu_release(ctx); spu_release(ctx);
return ret;
if (ret)
return -EFAULT;
*ppos = pos + size;
return size;
} }
static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment