Насколько я понимаю, для того, чтобы copy_to_user
потерпел неудачу, некоторые адреса в пределах диапазона должны быть не записанными или не отображенными. Ваш type to[1]
- это просто адрес где-то на странице памяти пользовательского пространства; если он находится в стеке, адрес сразу после конца всегда будет доступен для записи, потому что стек уменьшается (если вы не используете HPPA, чего вы почти наверняка нет); если вы поместите его в сегмент данных, вам нужно будет очень тщательно все настроить, чтобы убедиться, что он был в самом конце сегмента данных, и сразу после этого ничего не было; в принципе malloc
выделение может не иметь ничего сразу после этого, но если вы не используете распределитель, такой как ElectricFence, который преднамеренно помещает не отображенные защитные страницы сразу после каждого выделения, он почти наверняка не будет.
Чтобы преднамеренно настроить ситуацию, когда запись обращается как к доступной, так и к недоступной памяти, вы можете сделать что-то вроде этого:
size_t pagesize = sysconf(_SC_PAGESIZE);
char *to_allocation = mmap(0, 2*pagesize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
memset(to_allocation, 0x55, 2*pagesize); // force allocation
mprotect(to_allocation + pagesize, pagesize, PROT_NONE);
foo(to_allocation + pagesize - sizeof(type));
(Но с обработкой ошибок, конечно.)