copy_from_user警告大小不可certificate是正确的?

我在编译我的内核模块时遇到了一个警告,我无法解决这个问题。

首先来看看这个简化的代码:

#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; } 

我得到的警告如下:

警告:调用带有属性警告声明的’copy_from_user_overflow’:copy_from_user()缓冲区大小不可certificate是正确的

如你所见,这是完全错误的。 我读的数据amount可以certificate是好的! 我发现这个链接说min可以在最后一个参数中使用来使gcc静音,但它对我不起作用(我写道:

 if (copy_from_user(command, buf, min((unsigned long)amount, count))) 

无济于事。

有谁知道如何让gcc知道这很酷,它不应该担心?


另一个发生这种情况的地方如下:

 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; } 

在这种情况下,gcc也给了我相同的警告,即使它肯定是正确的。


这是确切的错误:

 In file included from /usr/src/linux-2.6.35.9-rtai-9jan2012/arch/x86/include/asm/uaccess.h:571:0, from :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 

内核版本:用rtai修补2.6.35.9(如你所见)

在您的第一个示例中,尝试替换

 min((unsigned long)amount, count) 

 min((unsigned long)READ_CHUNK, count) 

现在,可以certificate复制大小在编译时本身不会超过100个字节,因此说服gcc我们永远不会覆盖目标缓冲区command ,也就是100个字节。

在第二个示例中, read_buffercount都不在编译时知道。 如果您不希望此错误让您陷入困境,则需要编译时可评估参数 (目标缓冲区和副本大小)发送到copy_from_user

如果检查主线linux内核,很难找到将用户空间数据写入内核中的malloced缓冲区的示例。 所以我想,如果你的代码必须非常安全,你需要取消缓冲区的mallocing

PS :了解gcc如何实现有限的缓冲区溢出保护机制,可以防止一些缓冲区溢出攻击。