2004-01-21 19:47:10

by Dave Jones

[permalink] [raw]
Subject: Large stack allocation in w9966 driver.

Another large on-stack allocation. (This time around 2KB).

Dave


diff -Nru a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
--- a/drivers/media/video/w9966.c Wed Jan 21 19:10:44 2004
+++ b/drivers/media/video/w9966.c Wed Jan 21 19:10:44 2004
@@ -875,6 +875,7 @@
unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000
unsigned char* dest = (unsigned char*)buf;
unsigned long dleft = count;
+ unsigned char *tbuf;

// Why would anyone want more than this??
if (count > cam->width * cam->height * 2)
@@ -894,11 +895,14 @@
w9966_pdev_release(cam);
return -EFAULT;
}
-
+
+ tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
+ if (tbuf == NULL)
+ return -ENOMEM;
+
while(dleft > 0)
{
unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
- unsigned char tbuf[W9966_RBUFFER];

if (parport_read(cam->pport, tbuf, tsize) < tsize) {
w9966_pdev_release(cam);
@@ -911,7 +915,8 @@
dest += tsize;
dleft -= tsize;
}
-
+ kfree(tbuf);
+
w9966_wReg(cam, 0x01, 0x18); // Disable capture
w9966_pdev_release(cam);


2004-01-21 20:02:54

by Dave Jones

[permalink] [raw]
Subject: Re: Large stack allocation in w9966 driver.

On Wed, Jan 21, 2004 at 07:45:59PM +0000, Dave Jones wrote:
> Another large on-stack allocation. (This time around 2KB).

Lets try again, without the leaks. (Thanks Joe).

Dave

--- bk-linus/drivers/media/video/w9966.c 2003-09-29 20:04:12.000000000 +0100
+++ linux-2.5/drivers/media/video/w9966.c 2004-01-21 20:00:02.000000000 +0000
@@ -875,6 +875,7 @@
unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000
unsigned char* dest = (unsigned char*)buf;
unsigned long dleft = count;
+ unsigned char *tbuf;

// Why would anyone want more than this??
if (count > cam->width * cam->height * 2)
@@ -894,25 +895,33 @@
w9966_pdev_release(cam);
return -EFAULT;
}
-
+
+ tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
+ if (tbuf == NULL) {
+ count = -ENOMEM;
+ goto out;
+ }
+
while(dleft > 0)
{
unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
- unsigned char tbuf[W9966_RBUFFER];

if (parport_read(cam->pport, tbuf, tsize) < tsize) {
- w9966_pdev_release(cam);
- return -EFAULT;
+ count = -EFAULT;
+ goto out;
}
if (copy_to_user(dest, tbuf, tsize) != 0) {
- w9966_pdev_release(cam);
- return -EFAULT;
+ count = -EFAULT;
+ goto out;
}
dest += tsize;
dleft -= tsize;
}
-
+
w9966_wReg(cam, 0x01, 0x18); // Disable capture
+
+out:
+ kfree(tbuf);
w9966_pdev_release(cam);

return count;