Я пишу обработчик ioctls для модуля ядра и хочу скопировать данные из пространства пользователя. Когда я компилирую код с отключенными оптимизациями (-O0 -g
flags), компилятор возвращает следующую ошибку: ./include/linux/thread_info.h:136:17: error: call to ‘__bad_copy_to’ declared with attribute error: copy destination size is too small
. Мой код:
struct my_struct {
int x;
int y;
}
...
long ioctl_handler(struct file *filp, unsigned int cmd, unsigned long arg) {
switch(cmd) {
case MY_IOCTL_ID:
struct my_struct *cmd_info = vmalloc(sizeof(struct my_struct));
if (!cmd_info)
//error handling
if (copy_from_user(cmd_info, (void __user*)arg, sizeof(struct my_struct)))
//error handling
//perform some action
vfree(cmd_info);
return 0;
}
}
Когда я объявляю переменную в стеке (struct my_struct cmd_info;
) вместо использования vmallo c, проблема исчезает, и модуль компилируется без каких-либо ошибок, но я бы хотел избежать этого решения. Также при использовании -O2
компиляция флага успешна.
После быстрого взгляда на внутренние компоненты ядра Я нашел место, откуда возвращается ошибка, но я считаю, что это не должно произойти в моем случае, потому что __compiletime_object_size(addr)
равно sizeof(struct my_struct)
int sz = __compiletime_object_size(addr);
if (unlikely(sz >= 0 && sz < bytes)) {
if (!__builtin_constant_p(bytes))
copy_overflow(sz, bytes);
else if (is_source)
__bad_copy_from();
else
__bad_copy_to();
return false;
}