Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=aa0ed2bdb663608d5e409faecff3e1e81a3d413a
Commit:     aa0ed2bdb663608d5e409faecff3e1e81a3d413a
Parent:     f194bda4ce7e71cc95535f494a4a5515cd91ed85
Author:     Arnd Bergmann <[EMAIL PROTECTED]>
AuthorDate: Sat Mar 10 00:05:35 2007 +0100
Committer:  Arnd Bergmann <[EMAIL PROTECTED]>
CommitDate: Sat Mar 10 00:07:48 2007 +0100

    [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: Arnd Bergmann <[EMAIL PROTECTED]>
    Cc: Ulrich Weigand <[EMAIL PROTECTED]>
---
 arch/powerpc/platforms/cell/spufs/file.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/file.c 
b/arch/powerpc/platforms/cell/spufs/file.c
index b00653d..505266a 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -63,8 +63,8 @@ static ssize_t
 spufs_mem_read(struct file *file, char __user *buffer,
                                size_t size, loff_t *pos)
 {
-       int ret;
        struct spu_context *ctx = file->private_data;
+       ssize_t ret;
 
        spu_acquire(ctx);
        ret = __spufs_mem_read(ctx, buffer, size, pos);
@@ -74,25 +74,29 @@ spufs_mem_read(struct file *file, char __user *buffer,
 
 static ssize_t
 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;
        char *local_store;
+       loff_t pos = *ppos;
        int ret;
 
-       size = min_t(ssize_t, LS_SIZE - *pos, size);
-       if (size <= 0)
+       if (pos < 0)
+               return -EINVAL;
+       if (pos > LS_SIZE)
                return -EFBIG;
-       *pos += size;
+       if (size > LS_SIZE - pos)
+               size = LS_SIZE - pos;
 
        spu_acquire(ctx);
-
        local_store = ctx->ops->get_ls(ctx);
-       ret = copy_from_user(local_store + *pos - size,
-                            buffer, size) ? -EFAULT : size;
-
+       ret = copy_from_user(local_store + pos, buffer, size);
        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,
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to