强制copy_to_user()失败

时间:2018-05-01 21:11:38

标签: linux-kernel system-calls

我正在尝试编写一个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目的地的内存?

如何让它失败?

感谢。

2 个答案:

答案 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);