[CHECKER][PATCH] cmpci user-pointer fix

From: Hollis Blanchard (hollisb@us.ibm.com)
Date: Wed May 28 2003 - 15:21:24 EST


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: cmpci-userptr.diff
Description: Binary data