Nasty buffer overflow in i2c-proc.c solved.

This one was not nice at all. When /proc/bus/i2c-* is read, information is
put into a kernel buffer, which was declared to be the same size as the
final user-space buffer into which it should be copied. Information was
copied into the kernel buffer line by line (using sprintf). If the
buffer is smaller than the whole /proc/bus/i2c-*, only part of the file
was copied. But if the buffer did not break on a line-break, the sprintf
wrote beyond the kernel buffer. With devastating results. Solution: make
the kernel buffer a little longer, so that a single additional line would
fit into it.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@431 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Frodo Looijaard committed 1999-04-29 17:29:11 +00:00
1 parent 1ade24f919
commit 8cbbcb8ec4
1 file changed
+8 -5
+8 -5
View File
@@ -259,10 +259,11 @@ int read_bus_i2c(char *buf, char **start, off_t offset, int len, int unused)
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
{
int i;
len = 0;
for (i = 0; i < I2C_ADAP_MAX; i++)
int nr = 0;
/* Note that it is safe to write a `little' beyond len. Yes, really. */
for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++)
if (i2cproc_adapters[i])
len += sprintf(buf+len, "i2c-%d\t%s\t%-32s\t%-32s\n",
nr += sprintf(buf+nr, "i2c-%d\t%s\t%-32s\t%-32s\n",
i2c_adapter_id(i2cproc_adapters[i]),
i2c_is_smbus_adapter(i2cproc_adapters[i])?"smbus":
#ifdef DEBUG
@@ -271,7 +272,7 @@ int read_bus_i2c(char *buf, char **start, off_t offset, int len, int unused)
"i2c",
i2cproc_adapters[i]->name,
i2cproc_adapters[i]->algo->name);
return len;
return nr;
}
/* This function generates the output for /proc/bus/i2c-? */
@@ -295,7 +296,9 @@ int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf,
count = 4000;
for (i = 0; i < I2C_ADAP_MAX; i++)
if (i2cproc_inodes[i] == inode->i_ino) {
if (! (kbuf = kmalloc(count,GFP_KERNEL)))
/* We need a bit of slack in the kernel buffer; this makes the
sprintf safe. */
if (! (kbuf = kmalloc(count + 80,GFP_KERNEL)))
return -ENOMEM;
for (j = 0; j < I2C_CLIENT_MAX; j++)
if ((client = i2cproc_adapters[i]->clients[j]))