public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [CHECKER][PATCH] cmpci user-pointer fix
@ 2003-05-28 20:17 Hollis Blanchard
  2003-05-28 20:31 ` Junfeng Yang
  2003-05-28 23:06 ` Raja R Harinath
  0 siblings, 2 replies; 3+ messages in thread
From: Hollis Blanchard @ 2003-05-28 20:17 UTC (permalink / raw)
  To: linux-kernel; +Cc: Junfeng Yang

[-- Attachment #1: Type: text/plain, Size: 2659 bytes --]

Here's what the Stanford tool said:
---------------------------------------------------------
[BUG] at least bad programming practice. file_operations.write ->
cm_write -> trans_ac3. write can take tainted. write can take tainted
inputs. the pointer is vefied in cm_write

/home/junfeng/linux-2.5.63/sound/oss/cmpci.c:593:trans_ac3:
ERROR:TAINTED:593:593: dereferencing tainted ptr 'src' [Callstack:
/home/junfeng/linux-2.5.63/fs/read_write.c:307:vfs_write((tainted
1)(tainted 2)) ->
/home/junfeng/linux-2.5.63/fs/read_write.c:241:cm_write((tainted
1)(tainted 2)) ->
/home/junfeng/linux-2.5.63/sound/oss/cmpci.c:1662:trans_ac3((tainted
2))]

         unsigned long data;
         unsigned long *dst = (unsigned long *) dest;
         unsigned short *src = (unsigned short *)source;

         do {

Error --->
                 data = (unsigned long) *src++;
                 data <<= 12;                    // ok for 16-bit data
                 if (s->spdif_counter == 2 || s->spdif_counter == 3)
---------------------------------------------------------
[BUG] at least bad programming practice. file_operations.write ->
cm_write -> trans_ac3. write can take tainted. write can take tainted
inputs. the pointer is vefied in cm_write

/home/junfeng/linux-2.5.63/sound/oss/cmpci.c:593:trans_ac3:
ERROR:TAINTED:593:593: dereferencing tainted ptr 'src' [Callstack:
/home/junfeng/linux-2.5.63/fs/read_write.c:307:vfs_write((tainted
1)(tainted 2)) ->
/home/junfeng/linux-2.5.63/fs/read_write.c:241:cm_write((tainted
1)(tainted 2)) ->
/home/junfeng/linux-2.5.63/sound/oss/cmpci.c:1662:trans_ac3((tainted
2))]

         unsigned long data;
         unsigned long *dst = (unsigned long *) dest;
         unsigned short *src = (unsigned short *)source;

         do {

Error --->
                 data = (unsigned long) *src++;
                 data <<= 12;                    // ok for 16-bit data
                 if (s->spdif_counter == 2 || s->spdif_counter == 3)
                         data |= 0x40000000;     // indicate AC-3 raw 
data
---------------------------------------------------------

I believe the attached patch fixes it. cm_write was calling access_ok, 
but after that you must still access user space through the 
get/put/copy*_user functions. It should be safe to return -EFAULT at 
these points in cm_write, since there are other returns already in the 
code above and below that. Compile-tested only.

Junfeng, the checker seems to have missed the "*dst0++ = *src++;" bits 
at the bottom of the patch... or at least it wasn't in the mail I saw 
("4 potential user-pointer errors", 2 May 2003).

-- 
Hollis Blanchard
IBM Linux Technology Center

[-- Attachment #2: cmpci-userptr.diff --]
[-- Type: application/octet-stream, Size: 1916 bytes --]

--- linux-2.5.70/sound/oss/cmpci.c.orig	Sat May 24 19:00:00 2003
+++ linux-2.5.70/sound/oss/cmpci.c	Wed May 28 14:53:15 2003
@@ -580,15 +580,17 @@
 	spin_unlock_irqrestore(&s->lock, flags);
 }
 
-static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
 {
 	int   i = size / 2;
+	int err;
 	unsigned long data;
 	unsigned long *dst = (unsigned long *) dest;
 	unsigned short *src = (unsigned short *)source;
 
 	do {
-		data = (unsigned long) *src++;
+		if ((err = __get_user(data, src++)))
+			return err;
 		data <<= 12;			// ok for 16-bit data
 		if (s->spdif_counter == 2 || s->spdif_counter == 3)
 			data |= 0x40000000;	// indicate AC-3 raw data
@@ -605,6 +607,8 @@
 		if (s->spdif_counter == 384)
 			s->spdif_counter = 0;
 	} while (--i);
+
+	return 0;
 }
 
 static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
@@ -1655,13 +1659,16 @@
 			continue;
 		}
 		if (s->status & DO_AC3_SW) {
+			int err;
+
 			// clip exceeded data, caught by 033 and 037
 			if (swptr + 2 * cnt > s->dma_dac.dmasize)
 				cnt = (s->dma_dac.dmasize - swptr) / 2;
-			trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt);
+			if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt)))
+				return err;
 			swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
 		} else if (s->status & DO_DUAL_DAC) {
-			int	i;
+			int	i, err;
 			unsigned long *src, *dst0, *dst1;
 
 			src = (unsigned long *) buffer;
@@ -1669,8 +1676,10 @@
 			dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
 			// copy left/right sample at one time
 			for (i = 0; i <= cnt / 4; i++) {
-				*dst0++ = *src++;
-				*dst1++ = *src++;
+				if ((err = __get_user(*dst0++, src++)))
+					return err;
+				if ((err = __get_user(*dst1++, src++)))
+					return err;
 			}
 			swptr = (swptr + cnt) % s->dma_dac.dmasize;
 		} else {

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [CHECKER][PATCH] cmpci user-pointer fix
  2003-05-28 20:17 [CHECKER][PATCH] cmpci user-pointer fix Hollis Blanchard
@ 2003-05-28 20:31 ` Junfeng Yang
  2003-05-28 23:06 ` Raja R Harinath
  1 sibling, 0 replies; 3+ messages in thread
From: Junfeng Yang @ 2003-05-28 20:31 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linux-kernel

> ---------------------------------------------------------
>
> I believe the attached patch fixes it. cm_write was calling access_ok,
> but after that you must still access user space through the
> get/put/copy*_user functions. It should be safe to return -EFAULT at
> these points in cm_write, since there are other returns already in the
> code above and below that. Compile-tested only.

Thanks a lot for the fixes!

>
> Junfeng, the checker seems to have missed the "*dst0++ = *src++;" bits
> at the bottom of the patch... or at least it wasn't in the mail I saw
> ("4 potential user-pointer errors", 2 May 2003).

I deliberately surpressed 'redudant' error reports.  When the checker saw
multiple errors caused by the same user pointer in one function, it'll
only report one error for this user pointer in this function.  if I don't
do so, people tend to get bored by the 'repeated' messages, and leave
error reports in other functions uninspected. ;) I'll re-run the checker
soon with the suppression off.

-Junfeng


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [CHECKER][PATCH] cmpci user-pointer fix
  2003-05-28 20:17 [CHECKER][PATCH] cmpci user-pointer fix Hollis Blanchard
  2003-05-28 20:31 ` Junfeng Yang
@ 2003-05-28 23:06 ` Raja R Harinath
  1 sibling, 0 replies; 3+ messages in thread
From: Raja R Harinath @ 2003-05-28 23:06 UTC (permalink / raw)
  To: linux-kernel

Hi,

Hollis Blanchard <hollisb@us.ibm.com> writes:
[snip]
> I believe the attached patch fixes it. cm_write was calling access_ok,
> but after that you must still access user space through the
> get/put/copy*_user functions. It should be safe to return -EFAULT at
> these points in cm_write, since there are other returns already in the
> code above and below that. Compile-tested only.
[snip]
> --- linux-2.5.70/sound/oss/cmpci.c.orig	Sat May 24 19:00:00 2003
> +++ linux-2.5.70/sound/oss/cmpci.c	Wed May 28 14:53:15 2003
> @@ -580,15 +580,17 @@
>  	spin_unlock_irqrestore(&s->lock, flags);
>  }
>  
> -static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
> +static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)

Shouldn't 'source' get the new __user annotation, then:

  const char * __user source

IIRC.

>  {
>  	int   i = size / 2;
> +	int err;
>  	unsigned long data;
>  	unsigned long *dst = (unsigned long *) dest;
>  	unsigned short *src = (unsigned short *)source;

Likewise with 'src'.

- Hari
-- 
Raja R Harinath ------------------------------ harinath@cs.umn.edu


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-05-28 22:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-28 20:17 [CHECKER][PATCH] cmpci user-pointer fix Hollis Blanchard
2003-05-28 20:31 ` Junfeng Yang
2003-05-28 23:06 ` Raja R Harinath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox