copy_from_user警告在尺寸上不正确吗? [英] copy_from_user warning on size not being provably correct?

查看:334
本文介绍了copy_from_user警告在尺寸上不正确吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译内核模块时遇到警告,提示我无法解决.

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

我得到的警告如下:

警告:调用带有属性警告声明的"copy_from_user_overflow":copy_from_user()缓冲区大小无法证明正确

warning: call to ‘copy_from_user_overflow’ declared with attribute warning: copy_from_user() buffer size is not provably correct

如您所见,这是完全错误的.我读取的数据的amount证明是可以的!我发现

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)))

无济于事.

有人知道如何让gcc知道这很酷,也不必担心吗?

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

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

在这种情况下,即使确实正确,gcc也会给我同样的警告.

In this case also gcc gives me the same warning, even though it is surely correct.

这是确切的错误:

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

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

Kernel version: 2.6.35.9 patched with rtai (as you can see)

推荐答案

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

In your first example, try replacing

min((unsigned long)amount, count)

使用

min((unsigned long)READ_CHUNK, count)

现在,可以证明,在编译时本身,复制大小不会超过100个字节,因此使gcc确信我们将永远不会覆盖同样为100个字节的目标缓冲区command.

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.

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

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

如果检查主线的linux内核,将很难找到示例将用户空间数据写入内核内部的malloc缓冲区中的示例.所以我想,如果您的代码必须绝对安全,则需要取消缓冲区的分配

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 :了解gcc如何实现有限的

PS: Read about how gcc implements a limited buffer overflow protection mechanism that can prevent some buffer overflow attacks.

这篇关于copy_from_user警告在尺寸上不正确吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆