我正在尝试编写一个copy_to_user()失败的测试(只复制一些数据,或者根本不复制,不使用NULL指针),但是不成功。
在用户模式下的测试有以下几行:
type to[1];
foo(to);
foo是一个包装函数,它调用具有以下行的系统调用:
type from[2] = {something1, something2};
int not_copied = copy_to_user(to, from, sizeof(type) * 2);
事实证明not_copied为0,即使我尝试将malloc用于“type to”声明。此外,'to [0]'和'to [1]'分别是'something1'和'something2'。
我是否正确地认为我的'type to'声明不会限制copy_to_user目的地的内存?
如何让它失败?
感谢。
答案 0 :(得分:1)
据我了解,为了使type to[1]
失败,范围内的某些地址实际上必须是不可写入或未映射的。您的malloc
只是用户空间内存页面中的某个地址;如果它在堆栈中,结束后的地址将始终是可写的,因为堆栈会逐渐减少(除非你在HPPA上,你几乎肯定不会)。如果你把它放在数据段中,你必须非常仔细地设置,以确保它在数据段的末尾是正确的,之后没有任何内容;原则上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));
分配可能之后不会立即执行任何操作,但除非您使用像ElectricFence这样的分配器在每次分配后立即故意放置未映射的防护页面,否则它几乎肯定会赢得&# 39;吨
为了有意识地设置写访问可访问和无法访问的内存的情况,你可以这样做:
rows
(但当然是错误处理。)
答案 1 :(得分:0)
我设法通过进行这些更改使其可靠地失败:
type to[SMALL_INTEGER]
foo(to)
包装器有:
type from[HUGE_INTEGER]
// fill from with huge amount of data <- unsure if this part is necessary
int not_copied = copy_to_user(to, from, sizeof(type) * HUGE_INTEGER);