[LWN Logo]
[LWN.net]
From:	 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
To:	 Linus Torvalds <torvalds@transmeta.com>
Subject: [BKPATCH] OSS: Re: AUDIT of 2.5.15 copy_to/from_user
Date:	 Sat, 18 May 2002 21:14:39 -0300
Cc:	 Rusty Russell <rusty@rustcorp.com.au>,	linux-kernel@vger.kernel.org,
	 kernel-janitor-discuss@lists.sourceforge.net

Em Sat, May 18, 2002 at 08:54:19PM -0300, Arnaldo C. Melo escreveu:
> Em Sat, May 18, 2002 at 07:55:35PM -0300, Arnaldo C. Melo escreveu:
> > Heads up: I'm finishing a bk changeset for intermezzo, will be submitting
> > to Linus in some minutes.
> 
> Second heads up:
> 
> OSS will be on its way to Linus in some minutes...

Here it is the OSS one... Linus, please consider pulling it from:

http://kernel-acme.bkbits.net:8080/oss-copy_tofrom_user-2.5

- Arnaldo

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.540   -> 1.540.1.1
#	   sound/oss/cmpci.c	1.12    -> 1.13   
#	  sound/oss/cs46xx.c	1.17    -> 1.18   
#	sound/oss/msnd_pinnacle.c	1.7     -> 1.8    
#	sound/oss/esssolo1.c	1.12    -> 1.13   
#	 sound/oss/ite8172.c	1.6     -> 1.7    
#	  sound/oss/es1371.c	1.11    -> 1.12   
#	sound/oss/gus_wave.c	1.4     -> 1.5    
#	sound/oss/sb_audio.c	1.3     -> 1.4    
#	sound/oss/via82cxxx_audio.c	1.20    -> 1.21   
#	 sound/oss/maestro.c	1.10    -> 1.11   
#	 sound/oss/rme96xx.c	1.6     -> 1.7    
#	 sound/oss/midibuf.c	1.3     -> 1.4    
#	sound/oss/sonicvibes.c	1.11    -> 1.12   
#	sound/oss/emu10k1/passthrough.c	1.4     -> 1.5    
#	  sound/oss/es1370.c	1.12    -> 1.13   
#	sound/oss/sequencer.c	1.2     -> 1.3    
#	   sound/oss/vwsnd.c	1.4     -> 1.5    
#	sound/oss/wavfront.c	1.10    -> 1.11   
#	sound/oss/emu10k1/cardwi.c	1.5     -> 1.6    
#	sound/oss/i810_audio.c	1.23    -> 1.24   
#	 sound/oss/trident.c	1.20    -> 1.21   
#	sound/oss/emu10k1/cardwo.c	1.6     -> 1.7    
#	sound/oss/maestro3.c	1.16    -> 1.17   
#	sound/oss/cs4281/cs4281m.c	1.13    -> 1.14   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/19	acme@conectiva.com.br	1.541
# fs/intermezzo/ext_attr.c
# fs/intermezzo/kml.c
# fs/intermezzo/psdev.c
# 
# 	- fix copy_{to,from}_user error handling (thans to Rusty for pointing this out)
# --------------------------------------------
# 02/05/19	acme@conectiva.com.br	1.540.1.1
# drivers/sound/*.c
# 
# 	- fix copy_{to,from}_user error handling (thanks to Rusty for pointing this out)
# --------------------------------------------
#
diff -Nru a/sound/oss/cmpci.c b/sound/oss/cmpci.c
--- a/sound/oss/cmpci.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/cmpci.c	Sun May 19 03:08:22 2002
@@ -2032,7 +2032,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -2049,7 +2051,9 @@
 				s->dma_adc.count &= s->dma_adc.fragsize-1;
 		}
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
--- a/sound/oss/cs4281/cs4281m.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/cs4281/cs4281m.c	Sun May 19 03:08:22 2002
@@ -3496,7 +3496,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize - 1;
 		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+		if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -3520,7 +3522,9 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize - 1;
 		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+		if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
--- a/sound/oss/cs46xx.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/cs46xx.c	Sun May 19 03:08:22 2002
@@ -2965,7 +2965,9 @@
 			cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift;
 			cinfo.ptr = dmabuf->hwptr/dmabuf->divisor;
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+				return -EFAULT;
+			return 0;
 		}
 		return -ENODEV;
 
@@ -2998,7 +3000,9 @@
 			    "cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n",
 				cinfo.bytes,cinfo.blocks,cinfo.ptr) );
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+				return -EFAULT;
+			return 0;
 		}
 		return -ENODEV;
 
diff -Nru a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c
--- a/sound/oss/emu10k1/cardwi.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/emu10k1/cardwi.c	Sun May 19 03:08:22 2002
@@ -304,9 +304,10 @@
 
 static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
 {
-	if (cov == 1)
-		__copy_to_user(dst, src + str, len);
-	else {
+	if (cov == 1) {
+		if (__copy_to_user(dst, src + str, len))
+			return;
+	} else {
 		u8 byte;
 		u32 i;
 
@@ -314,7 +315,8 @@
 
 		for (i = 0; i < len; i++) {
 			byte = src[2 * i] ^ 0x80;
-			__copy_to_user(dst + i, &byte, 1);
+			if (__copy_to_user(dst + i, &byte, 1))
+				return;
 		}
 	}
 }
diff -Nru a/sound/oss/emu10k1/cardwo.c b/sound/oss/emu10k1/cardwo.c
--- a/sound/oss/emu10k1/cardwo.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/emu10k1/cardwo.c	Sun May 19 03:08:22 2002
@@ -483,14 +483,17 @@
 
 	if (len > PAGE_SIZE - pgoff) {
 		k = PAGE_SIZE - pgoff;
-		__copy_from_user((u8 *)dst[pg] + pgoff, src, k);
+		if (__copy_from_user((u8 *)dst[pg] + pgoff, src, k))
+			return;
 		len -= k;
 		while (len > PAGE_SIZE) {
-			__copy_from_user(dst[++pg], src + k, PAGE_SIZE);
+			if (__copy_from_user(dst[++pg], src + k, PAGE_SIZE))
+				return;
 			k += PAGE_SIZE;
 			len -= PAGE_SIZE;
 		}
-		__copy_from_user(dst[++pg], src + k, len);
+		if (__copy_from_user(dst[++pg], src + k, len))
+			return;
 
 	} else
 		__copy_from_user((u8 *)dst[pg] + pgoff, src, len);
@@ -515,7 +518,8 @@
 
 	while (len) { 
 		for (voice_num = 0; voice_num < woinst->num_voices; voice_num++) {
-			__copy_from_user((u8 *)(mem[voice_num].addr[pg]) + pgoff, src, woinst->format.bytespervoicesample);
+			if (__copy_from_user((u8 *)(mem[voice_num].addr[pg]) + pgoff, src, woinst->format.bytespervoicesample))
+				return;
 			src += woinst->format.bytespervoicesample;
 		}
 
diff -Nru a/sound/oss/emu10k1/passthrough.c b/sound/oss/emu10k1/passthrough.c
--- a/sound/oss/emu10k1/passthrough.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/emu10k1/passthrough.c	Sun May 19 03:08:22 2002
@@ -165,12 +165,15 @@
 
 		DPD(3, "prepend size %d, prepending %d bytes\n", pt->prepend_size, needed);
 		if (count < needed) {
-			copy_from_user(pt->buf + pt->prepend_size, buffer, count);
+			if (copy_from_user(pt->buf + pt->prepend_size, buffer,
+					   count))
+				return -EFAULT;
 			pt->prepend_size += count;
 			DPD(3, "prepend size now %d\n", pt->prepend_size);
 			return count;
 		}
-		copy_from_user(pt->buf + pt->prepend_size, buffer, needed);
+		if (copy_from_user(pt->buf + pt->prepend_size, buffer, needed))
+			return -EFAULT;
 		r = pt_putblock(wave_dev, (u16 *) pt->buf, nonblock);
 		if (r)
 			return r;
@@ -181,7 +184,8 @@
 	blocks_copied = 0;
 	while (blocks > 0) {
 		u16 *bufptr = (u16 *) buffer + (bytes_copied/2);
-		copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE);
+		if (copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE))
+			return -EFAULT;
 		bufptr = (u16 *) pt->buf;
 		r = pt_putblock(wave_dev, bufptr, nonblock);
 		if (r) {
@@ -197,7 +201,8 @@
 	i = count - bytes_copied;
 	if (i) {
 		pt->prepend_size = i;
-		copy_from_user(pt->buf, buffer + bytes_copied, i);
+		if (copy_from_user(pt->buf, buffer + bytes_copied, i))
+			return -EFAULT;
 		bytes_copied += i;
 		DPD(3, "filling prepend buffer with %d bytes", i);
 	}
diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c
--- a/sound/oss/es1370.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/es1370.c	Sun May 19 03:08:22 2002
@@ -1635,7 +1635,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1653,7 +1655,9 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -2112,7 +2116,9 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/es1371.c	Sun May 19 03:08:22 2002
@@ -1824,7 +1824,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1842,8 +1844,9 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
 			if ((val = prog_dmabuf_dac2(s)))
@@ -2292,7 +2295,9 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
diff -Nru a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
--- a/sound/oss/esssolo1.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/esssolo1.c	Sun May 19 03:08:22 2002
@@ -1468,7 +1468,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1492,7 +1494,9 @@
 		       cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
 		       s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
 #endif
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
--- a/sound/oss/gus_wave.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/gus_wave.c	Sun May 19 03:08:22 2002
@@ -1719,7 +1719,9 @@
 	 * been transferred already.
 	 */
 
-	copy_from_user(&((char *) &patch)[offs], &(addr)[offs], sizeof_patch - offs);
+	if (copy_from_user(&((char *) &patch)[offs], &(addr)[offs],
+			   sizeof_patch - offs))
+		return -EFAULT;
 
 	if (patch.mode & WAVE_ROM)
 		return -EINVAL;
@@ -1864,7 +1866,10 @@
 			 * OK, move now. First in and then out.
 			 */
 
-			copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, &(addr)[sizeof_patch + src_offs], blk_sz);
+			if (copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf,
+					   &(addr)[sizeof_patch + src_offs],
+					   blk_sz))
+				return -EFAULT;
 
 			save_flags(flags);
 			cli();
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/i810_audio.c	Sun May 19 03:08:22 2002
@@ -2020,7 +2020,9 @@
 		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
@@ -2059,8 +2061,9 @@
 		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
+		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 	case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
 		printk("SNDCTL_DSP_NONBLOCK\n");
diff -Nru a/sound/oss/ite8172.c b/sound/oss/ite8172.c
--- a/sound/oss/ite8172.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/ite8172.c	Sun May 19 03:08:22 2002
@@ -1427,7 +1427,9 @@
 	if (count < 0)
 	    count = 0;
 	cinfo.blocks = count >> s->dma_adc.fragshift;
-	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+	if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		return -EFAULT;
+	return 0;
 
     case SNDCTL_DSP_GETOPTR:
 	if (!(file->f_mode & FMODE_READ))
@@ -1448,7 +1450,9 @@
 	if (count < 0)
 	    count = 0;
 	cinfo.blocks = count >> s->dma_dac.fragshift;
-	return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+	if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		return -EFAULT;
+	return 0;
 
     case SNDCTL_DSP_GETBLKSIZE:
 	if (file->f_mode & FMODE_WRITE)
diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/maestro.c	Sun May 19 03:08:22 2002
@@ -2756,7 +2756,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -2771,7 +2773,9 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/maestro3.c b/sound/oss/maestro3.c
--- a/sound/oss/maestro3.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/maestro3.c	Sun May 19 03:08:22 2002
@@ -1805,7 +1805,9 @@
         if (s->dma_adc.mapped)
             s->dma_adc.count &= s->dma_adc.fragsize-1;
         spin_unlock_irqrestore(&s->lock, flags);
-        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+        if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		return -EFAULT;
+	return 0;
 
     case SNDCTL_DSP_GETOPTR:
         if (!(file->f_mode & FMODE_WRITE))
@@ -1818,7 +1820,9 @@
         if (s->dma_dac.mapped)
             s->dma_dac.count &= s->dma_dac.fragsize-1;
         spin_unlock_irqrestore(&s->lock, flags);
-        return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+        if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		return -EFAULT;
+	return 0;
 
     case SNDCTL_DSP_GETBLKSIZE:
         if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/midibuf.c b/sound/oss/midibuf.c
--- a/sound/oss/midibuf.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/midibuf.c	Sun May 19 03:08:22 2002
@@ -290,15 +290,15 @@
 				 */
 
 			if (file->f_flags & O_NONBLOCK) {
-				restore_flags(flags);
-				return -EAGAIN;
+				c = -EAGAIN;
+				goto out;
 			}
 
 			interruptible_sleep_on(&midi_sleeper[dev]);
 			if (signal_pending(current)) 
 			{
-				restore_flags(flags);
-				return -EINTR;
+				c = -EINTR;
+				goto out;
 			}
 			n = SPACE_AVAIL(midi_out_buf[dev]);
 		}
@@ -308,11 +308,15 @@
 		for (i = 0; i < n; i++)
 		{
 			/* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
-			copy_from_user((char *) &tmp_data, &(buf)[c], 1);
+			if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) {
+				c = -EFAULT;
+				goto out;
+			}
 			QUEUE_BYTE(midi_out_buf[dev], tmp_data);
 			c++;
 		}
 	}
+out:
 	restore_flags(flags);
 	return c;
 }
@@ -333,8 +337,8 @@
 						 * No data yet, wait
 						 */
  		if (file->f_flags & O_NONBLOCK) {
- 			restore_flags(flags);
- 			return -EAGAIN;
+ 			c = -EAGAIN;
+			goto out;
  		}
 		interruptible_sleep_on_timeout(&input_sleeper[dev],
 					       parms[dev].prech_timeout);
@@ -357,10 +361,14 @@
 			REMOVE_BYTE(midi_in_buf[dev], tmp_data);
 			fixit = (char *) &tmp_data;
 			/* BROKE BROKE BROKE */
-			copy_to_user(&(buf)[c], fixit, 1);
+			if (copy_to_user(&(buf)[c], fixit, 1)) {
+				c = -EFAULT;
+				goto out;
+			}
 			c++;
 		}
 	}
+out:
 	restore_flags(flags);
 	return c;
 }
diff -Nru a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
--- a/sound/oss/msnd_pinnacle.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/msnd_pinnacle.c	Sun May 19 03:08:22 2002
@@ -564,11 +564,15 @@
 		mixer_info info;
 		set_mixer_info();
 		info.modify_counter = dev.mixer_mod_count;
-		return copy_to_user((void *)arg, &info, sizeof(info));
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
 	} else if (cmd == SOUND_OLD_MIXER_INFO) {
 		_old_mixer_info info;
 		set_mixer_info();
-		return copy_to_user((void *)arg, &info, sizeof(info));
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
 	} else if (cmd == SOUND_MIXER_PRIVATE1) {
 		dev.nresets = 0;
 		dsp_full_reset();
diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
--- a/sound/oss/rme96xx.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/rme96xx.c	Sun May 19 03:08:22 2002
@@ -1083,7 +1083,9 @@
 			dma->readptr &= s->fragsize<<1;
 		spin_unlock_irqrestore(&s->lock,flags);
 
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_READ))
@@ -1100,7 +1102,9 @@
 		if (dma->mmapped)
 			dma->writeptr &= s->fragsize<<1;
 		spin_unlock_irqrestore(&s->lock,flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
         case SNDCTL_DSP_GETBLKSIZE:
 	     return put_user(s->fragsize, (int *)arg);
 
@@ -1520,7 +1524,8 @@
 	VALIDATE_STATE(s);
 	if (cmd == SOUND_MIXER_PRIVATE1) {
 		rme_mixer mixer;
-		copy_from_user(&mixer,(void*)arg,sizeof(mixer));
+		if (copy_from_user(&mixer,(void*)arg,sizeof(mixer)))
+			return -EFAULT;
 		
 		if (file->f_mode & FMODE_WRITE) {
 		     s->dma[mixer.devnr].outoffset = mixer.o_offset;
@@ -1537,7 +1542,8 @@
 	}
 	if (cmd == SOUND_MIXER_PRIVATE3) {
 	     u32 control;
-	     copy_from_user(&control,(void*)arg,sizeof(control)); 
+	     if (copy_from_user(&control,(void*)arg,sizeof(control)))
+		     return -EFAULT;
 	     if (file->f_mode & FMODE_WRITE) {
 		  s->control_register = control;
 		  writel(control,s->iobase + RME96xx_control_register);
diff -Nru a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c
--- a/sound/oss/sb_audio.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/sb_audio.c	Sun May 19 03:08:22 2002
@@ -849,7 +849,9 @@
 	/* if not duplex no conversion */
 	if (!devc->fullduplex)
 	{
-		copy_from_user (localbuf + localoffs, userbuf + useroffs, len);
+		if (copy_from_user(localbuf + localoffs,
+				   userbuf + useroffs, len))
+			return -EFAULT;
 		*used = len;
 		*returned = len;
 	}
@@ -869,9 +871,10 @@
 		{
 			locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
 			/* << 1 in order to get 16 bit samples */
-			copy_from_user (lbuf16,
-					userbuf+useroffs + (p << 1),
-					locallen << 1);
+			if (copy_from_user(lbuf16,
+					   userbuf + useroffs + (p << 1),
+					   locallen << 1))
+				return -EFAULT;
 			for (i = 0; i < locallen; i++)
 			{
 				buf8[p+i] = ~((lbuf16[i] >> 8) & 0xff) ^ 0x80;
@@ -898,9 +901,10 @@
 		while (c)
 		{
 			locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
-			copy_from_user (lbuf8,
-					userbuf+useroffs + p,
-					locallen);
+			if (copy_from_user(lbuf8,
+					   userbuf+useroffs + p,
+					   locallen))
+				return -EFAULT;
 			for (i = 0; i < locallen; i++)
 			{
 				buf16[p+i] = (~lbuf8[i] ^ 0x80) << 8;
diff -Nru a/sound/oss/sequencer.c b/sound/oss/sequencer.c
--- a/sound/oss/sequencer.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/sequencer.c	Sun May 19 03:08:22 2002
@@ -116,13 +116,15 @@
 	while (iqlen && c >= ev_len)
 	{
 		char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
-		copy_to_user(&(buf)[p], fixit, ev_len);
+		if (copy_to_user(&(buf)[p], fixit, ev_len))
+			goto out;
 		p += ev_len;
 		c -= ev_len;
 
 		iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
 		iqlen--;
 	}
+out:
 	restore_flags(flags);
 	return count - c;
 }
@@ -226,7 +228,8 @@
 
 	while (c >= 4)
 	{
-		copy_from_user((char *) event_rec, &(buf)[p], 4);
+		if (copy_from_user((char *) event_rec, &(buf)[p], 4))
+			goto out;
 		ev_code = event_rec[0];
 
 		if (ev_code == SEQ_FULLSIZE)
@@ -262,7 +265,9 @@
 					seq_startplay();
 				return count - c;
 			}
-			copy_from_user((char *) &event_rec[4], &(buf)[p + 4], 4);
+			if (copy_from_user((char *)&event_rec[4],
+					   &(buf)[p + 4], 4))
+				goto out;
 
 		}
 		else
@@ -320,7 +325,7 @@
 
 	if (!seq_playing)
 		seq_startplay();
-
+out:
 	return count;
 }
 
diff -Nru a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
--- a/sound/oss/sonicvibes.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/sonicvibes.c	Sun May 19 03:08:22 2002
@@ -1802,7 +1802,9 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1820,7 +1822,9 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/trident.c	Sun May 19 03:08:22 2002
@@ -2447,7 +2447,8 @@
 		if (dmabuf->mapped)
 			dmabuf->count &= dmabuf->fragsize-1;
 		spin_unlock_irqrestore(&state->card->lock, flags);
-		ret = copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		ret = copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ?
+				-EFAULT : 0;
 		break;
 
 	case SNDCTL_DSP_GETOPTR:
diff -Nru a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
--- a/sound/oss/via82cxxx_audio.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/via82cxxx_audio.c	Sun May 19 03:08:22 2002
@@ -2526,7 +2526,7 @@
 		info.fragments,
 		info.bytes);
 
-	return copy_to_user (arg, &info, sizeof (info));
+	return copy_to_user(arg, &info, sizeof (info)) ? -EFAULT : 0;
 }
 
 
@@ -2570,7 +2570,7 @@
 		info.blocks,
 		info.ptr);
 
-	return copy_to_user (arg, &info, sizeof (info));
+	return copy_to_user(arg, &info, sizeof (info)) ? -EFAULT : 0;
 }
 
 
diff -Nru a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
--- a/sound/oss/vwsnd.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/vwsnd.c	Sun May 19 03:08:22 2002
@@ -2303,7 +2303,8 @@
 		if (nb > count)
 			nb = count;
 		DBGPV("nb = %d\n", nb);
-		copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb);
+		if (copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb))
+			return -EFAULT;
 		(void) swb_inc_u(rport, nb);
 		buffer += nb;
 		count -= nb;
@@ -2377,7 +2378,8 @@
 		if (nb > count)
 			nb = count;
 		DBGPV("nb = %d\n", nb);
-		copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb);
+		if (copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb))
+			return -EFAULT;
 		pcm_output(devc, 0, nb);
 		buffer += nb;
 		count -= nb;
@@ -2650,7 +2652,9 @@
 		DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETISPACE:	/* _SIOR ('P',13, audio_buf_info) */
 		DBGX("SNDCTL_DSP_GETISPACE\n");
@@ -2667,7 +2671,9 @@
 		DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_NONBLOCK:	/* _SIO  ('P',14) */
 		DBGX("SNDCTL_DSP_NONBLOCK\n");
@@ -2725,7 +2731,9 @@
 			rport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&rport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		if (copy_to_user((void *) arg, &info, sizeof info))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETOPTR:	/* _SIOR ('P',18, count_info) */
 		DBGX("SNDCTL_DSP_GETOPTR\n");
@@ -2747,7 +2755,9 @@
 			wport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&wport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		if (copy_to_user((void *) arg, &info, sizeof info))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETODELAY:	/* _SIOR ('P', 23, int) */
 		DBGX("SNDCTL_DSP_GETODELAY\n");
diff -Nru a/sound/oss/wavfront.c b/sound/oss/wavfront.c
--- a/sound/oss/wavfront.c	Sun May 19 03:08:22 2002
+++ b/sound/oss/wavfront.c	Sun May 19 03:08:22 2002
@@ -1525,8 +1525,9 @@
 	/* Copy in the header of the GUS patch */
 
 	sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; 
-	copy_from_user (&((char *) &guspatch)[offs],
-			&(addr)[offs], sizeof_patch - offs);
+	if (copy_from_user(&((char *) &guspatch)[offs],
+			   &(addr)[offs], sizeof_patch - offs))
+		return -EFAULT;
 
 	if ((i = wavefront_find_free_patch ()) == -1) {
 		return -EBUSY;
@@ -1662,7 +1663,7 @@
 	if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
 			    sizeof(wavefront_any))) {
 		printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
-		return -(EINVAL);
+		return -EFAULT;
 	}
 
 	DPRINT (WF_DEBUG_LOAD_PATCH, "download "
@@ -1676,47 +1677,53 @@
 	switch (header.subkey) {
 	case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
 
-		copy_from_user ((unsigned char *) &header.hdr.s,
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_sample));
+		if (copy_from_user((unsigned char *) &header.hdr.s,
+				   (unsigned char *) header.hdrptr,
+				   sizeof (wavefront_sample)))
+			return -EFAULT;
 
 		return wavefront_send_sample (&header, header.dataptr, 0);
 
 	case WF_ST_MULTISAMPLE:
 
-		copy_from_user ((unsigned char *) &header.hdr.s,
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_multisample));
+		if (copy_from_user((unsigned char *) &header.hdr.s,
+				   (unsigned char *) header.hdrptr,
+				   sizeof(wavefront_multisample)))
+			return -EFAULT;
 
 		return wavefront_send_multisample (&header);
 
 
 	case WF_ST_ALIAS:
 
-		copy_from_user ((unsigned char *) &header.hdr.a,
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_alias));
+		if (copy_from_user((unsigned char *) &header.hdr.a,
+				   (unsigned char *) header.hdrptr,
+				   sizeof (wavefront_alias)))
+			return -EFAULT;
 
 		return wavefront_send_alias (&header);
 
 	case WF_ST_DRUM:
-		copy_from_user ((unsigned char *) &header.hdr.d, 
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_drum));
+		if (copy_from_user((unsigned char *) &header.hdr.d, 
+				   (unsigned char *) header.hdrptr,
+				   sizeof (wavefront_drum)))
+			return -EFAULT;
 
 		return wavefront_send_drum (&header);
 
 	case WF_ST_PATCH:
-		copy_from_user ((unsigned char *) &header.hdr.p, 
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_patch));
+		if (copy_from_user((unsigned char *) &header.hdr.p, 
+				   (unsigned char *) header.hdrptr,
+				   sizeof (wavefront_patch)))
+			return -EFAULT;
 
 		return wavefront_send_patch (&header);
 
 	case WF_ST_PROGRAM:
-		copy_from_user ((unsigned char *) &header.hdr.pr, 
-				(unsigned char *) header.hdrptr,
-				sizeof (wavefront_program));
+		if (copy_from_user((unsigned char *) &header.hdr.pr, 
+				   (unsigned char *) header.hdrptr,
+				   sizeof (wavefront_program)))
+			return -EFAULT;
 
 		return wavefront_send_program (&header);
 
@@ -1931,10 +1938,12 @@
 	switch (cmd) {
 
 	case WFCTL_WFCMD:
-		copy_from_user (&wc, (void *) arg, sizeof (wc));
+		if (copy_from_user(&wc, (void *) arg, sizeof (wc)))
+			return -EFAULT;
 		
 		if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-			copy_to_user ((void *) arg, &wc, sizeof (wc));
+			if (copy_to_user ((void *) arg, &wc, sizeof (wc)))
+				return -EFAULT;
 		}
 
 		return err;
@@ -2995,8 +3004,10 @@
 					"> 255 bytes to FX\n");
 				return -(EINVAL);
 			}
-			copy_from_user (page_data, (unsigned char *) r->data[3],
-					r->data[2]);
+			if (copy_from_user(page_data,
+					   (unsigned char *)r->data[3],
+					   r->data[2]))
+				return -EFAULT;
 			pd = page_data;
 		}
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/