Question

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)

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top