copy_from_user warning on size not being provably correct?

試著忘記壹切 提交于 2019-12-11 11:06:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!