问题
I encountered a warning produced when compiling my kernel module that I can't get to work around.
First take a look at this simplified code:
#define READ_CHUNK 100u
static int _procfs_write(struct file *file, const char *buf, unsigned long count, void *data)
{
char command[READ_CHUNK];
unsigned long left = count;
while (left > 0)
{
unsigned int amount = left<READ_CHUNK?left:READ_CHUNK;
if (copy_from_user(command, buf, amount))
return -EFAULT;
buf += amount;
left -= amount;
/* process buffer */
}
return count;
}
The warning I get is the following:
warning: call to ‘copy_from_user_overflow’ declared with attribute warning: copy_from_user() buffer size is not provably correct
As you can see, this is completely wrong. amount
of data that I read is provably fine! I found this link saying min
can be used in the last parameter to silence gcc, but it didn't work for me (I wrote:
if (copy_from_user(command, buf, min((unsigned long)amount, count)))
to no avail).
Does anyone know how to let gcc know that this is cool and it shouldn't worry?
Another place where this happens is something like the following:
static int _procfs_write(struct file *file, const char *buf, unsigned long count, void *data)
{
char *read_buffer = vmalloc(count * sizeof(*read_buffer));
if (read_buffer == NULL)
return -ENOMEM;
if (copy_from_user(read_buffer, buf, count))
{
vfree(read_buffer);
return -EFAULT;
}
/* process buffer */
vfree(read_buffer);
return count;
}
In this case also gcc gives me the same warning, even though it is surely correct.
This is the exact error:
In file included from /usr/src/linux-2.6.35.9-rtai-9jan2012/arch/x86/include/asm/uaccess.h:571:0,
from <my source file>:7:
/usr/src/linux-2.6.35.9-rtai-9jan2012/arch/x86/include/asm/uaccess_32.h: In function ‘copy_from_user’:
/usr/src/linux-2.6.35.9-rtai-9jan2012/arch/x86/include/asm/uaccess_32.h:212:26: warning: call to ‘copy_from_user_overflow’ declared with attribute warning: copy_from_user() buffer size is not provably correct
Kernel version: 2.6.35.9 patched with rtai (as you can see)
回答1:
In your first example, try replacing
min((unsigned long)amount, count)
with
min((unsigned long)READ_CHUNK, count)
Now, it can be proved that copy size will not exceed 100 bytes at compile time itself and hence convince gcc that we will never overwrite the destination buffer command
which is also 100 bytes.
In your second example, neither read_buffer
nor count
are known at compile time. If you don't want this error to bog you, you need to send compile time evaluable parameters ( destination buffer and copy size ) to copy_from_user
If you check the mainlined linux kernel, you will hardly find examples where they are writing user space data into into a malloced buffer inside the kernel. So I guess, if your code has to be perfectly safe, you need to do away the mallocing of the buffer
PS: Read about how gcc implements a limited buffer overflow protection mechanism that can prevent some buffer overflow attacks.
来源:https://stackoverflow.com/questions/9993929/copy-from-user-warning-on-size-not-being-provably-correct