
From: Jan Harkes <jaharkes@cs.cmu.edu>

This patch adds bounds checks for tainted scalars (reported by Brian Fulton
and Ted Unangst, Coverity Inc.).

Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/coda/upcall.c     |   26 +++++++++++++++++++-------
 25-akpm/include/linux/coda.h |    4 ++--
 2 files changed, 21 insertions(+), 9 deletions(-)

diff -puN fs/coda/upcall.c~coda-bounds-checking fs/coda/upcall.c
--- 25/fs/coda/upcall.c~coda-bounds-checking	2005-01-10 17:29:40.402744768 -0800
+++ 25-akpm/fs/coda/upcall.c	2005-01-10 17:29:40.407744008 -0800
@@ -555,6 +555,11 @@ int venus_pioctl(struct super_block *sb,
 		goto exit;
         }
 
+        if (data->vi.out_size > VC_MAXDATASIZE) {
+		error = -EINVAL;
+		goto exit;
+	}
+
         inp->coda_ioctl.VFid = *fid;
     
         /* the cmd field was mutated by increasing its size field to
@@ -583,19 +588,26 @@ int venus_pioctl(struct super_block *sb,
 		       error, coda_f2s(fid));
 		goto exit; 
 	}
+
+	if (outsize < (long)outp->coda_ioctl.data + outp->coda_ioctl.len) {
+		error = -EINVAL;
+		goto exit;
+	}
         
 	/* Copy out the OUT buffer. */
         if (outp->coda_ioctl.len > data->vi.out_size) {
 		error = -EINVAL;
-        } else {
-		if (copy_to_user(data->vi.out, 
-				 (char *)outp + (long)outp->coda_ioctl.data, 
-				 data->vi.out_size)) {
-			error = -EFAULT;
-			goto exit;
-		}
+		goto exit;
         }
 
+	/* Copy out the OUT buffer. */
+	if (copy_to_user(data->vi.out,
+			 (char *)outp + (long)outp->coda_ioctl.data,
+			 outp->coda_ioctl.len)) {
+		error = -EFAULT;
+		goto exit;
+	}
+
  exit:
 	CODA_FREE(inp, insize);
 	return error;
diff -puN include/linux/coda.h~coda-bounds-checking include/linux/coda.h
--- 25/include/linux/coda.h~coda-bounds-checking	2005-01-10 17:29:40.403744616 -0800
+++ 25-akpm/include/linux/coda.h	2005-01-10 17:29:40.408743856 -0800
@@ -761,8 +761,8 @@ union coda_downcalls {
 struct ViceIoctl {
         void __user *in;        /* Data to be transferred in */
         void __user *out;       /* Data to be transferred out */
-        short in_size;          /* Size of input buffer <= 2K */
-        short out_size;         /* Maximum size of output buffer, <= 2K */
+        u_short in_size;        /* Size of input buffer <= 2K */
+        u_short out_size;       /* Maximum size of output buffer, <= 2K */
 };
 
 struct PioctlData {
_
