2012-04-03 5 views
1

Я столкнулся с предупреждением, созданным при компиляции моего модуля ядра, с которым я не могу работать.copy_from_user предупреждение о размере не является корректно правильным?

Сначала посмотрим на этот упрощенный код:

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

Предупреждение я получаю следующее:

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

Как вы можете видеть, это совершенно неправильно. amount данных, которые я прочитал, доказуемо отлично! Я нашел this link говоря 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; 
} 

В этом случае также НКУ дает мне такое же предупреждение, даже если это, конечно, правильно.


Это точная ошибка:

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 (как вы можете видеть)

+0

Можете ли вы также сообщить нам, какой файл выдается за это предупреждение?Какова версия вашего ядра и другие подобные детали? –

+0

@PavanManjunath, я сейчас нахожусь дома, но я вернусь к вам завтра утром – Shahbaz

ответ

2

В первом примере, попробуйте заменить

min((unsigned long)amount, count) 

с

min((unsigned long)READ_CHUNK, count) 

Теперь можно доказать, что копировать размер не будет превышать 100 байт на само время компиляции и, следовательно, убедить GCC, что мы никогда не будем переписывать буфер назначения command который также 100 байт.

В вашем втором примере ни read_buffer, ни count известны во время компиляции. Если вы не хотите, чтобы эта ошибка докучать вам, вы нужно отправить время компиляции оцениваемых параметров (буфер назначения и размер копии) в copy_from_user

Если проверить mainlined ядро ​​Linux, вы вряд ли найдете примеры где они записывают данные пользовательского пространства в встроенный буфер внутри ядра. Так что я думаю, если ваш код должен быть совершенно безопасны, что вам нужно сделать прочь mallocing буфера

PS: Прочитайте о том, как GCC реализует ограниченный buffer overflow protection механизм, который может предотвратить некоторые атаки на переполнение буфера.

+0

Хотя это должно быть 'min ((unsigned long) READ_CHUNK, amount)', потому что 'amount' - это то, что мне нужно прочитать, но все же это не решает проблему во втором случае, когда память динамически распределяется, и поэтому фиксированный размер, такой как 'READ_CHUNK', не существует! – Shahbaz

+0

Кстати, я пробовал то, что вы сказали (min og READ_CHUCK и количество), и я все равно получаю то же предупреждение – Shahbaz

+0

Предупреждает ли предупреждение, если вы скорректируете размер копии? Скажите что-то вроде 50 (<100) –