C语言 来自“Linux内核编程”的源代码示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6515227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Source code example from "Linux kernel programming"
提问by Mark
was reading Robert Love's book, chapter 5 on syscalls, and found this simple example a bit questionable:
正在阅读 Robert Love 的书,关于系统调用的第 5 章,发现这个简单的例子有点问题:
asmlinkage long sys_silly_copy(unsigned long *src, unsigned long *dst, unsigned long len)
{
unsigned long buf;
if (copy_from_user(&buf, src, len))
return -EFAULT;
...
}
As we see 'buf' is object of type 'unsigned long' and defined on the kernel stack, i.e. its initial value is likely garbage. Anyway is it valid to copy 'len' bytes in the stack where buf is, i.e. it could overwrite something useful? Perhaps this is fine only for this particular example?
正如我们所看到的,'buf' 是类型为 'unsigned long' 并在内核堆栈上定义的对象,即它的初始值可能是垃圾。无论如何,在 buf 所在的堆栈中复制“len”字节是否有效,即它可以覆盖一些有用的东西?也许这仅适用于这个特定示例?
回答by paxdiablo
It is veryquestionable. In fact, it's downright dangerous. I'll give the author the benefit of the doubt here since they're just trying to show how copy_from_userand copy_to_userwork but they really should have provided an example that wasn't so dangerous.
这是非常值得怀疑的。事实上,这是非常危险的。我会给作者一个怀疑的好处,因为他们只是想展示如何copy_from_user和copy_to_user工作,但他们真的应该提供一个不那么危险的例子。
Especiallysince the book waxes lyrical about how you mustbe extra careful:
特别是因为这本书抒情地讲述了你必须格外小心:
System calls must carefully verify all their parameters to ensure that they are valid and legal.The system call runs in kernel-space, and if the user can pass invalid input into the kernel without restraint, the system's security and stability can suffer.
系统调用必须仔细验证其所有参数,以确保它们有效合法。系统调用运行在内核空间中,如果用户可以不受约束地将无效输入传递到内核中,系统的安全性和稳定性就会受到影响。
and then provides a means for the user to totally annihilate the kernel :-)
然后为用户提供一种完全消灭内核的方法:-)
The text from the copy I have states:
我所拥有的副本中的文字指出:
Let's consider an example system call that uses both
copy_from_user()andcopy_to_user().This syscall,silly_copy(), is utterly worthless; it copies data from its first parameter into its second.This is suboptimal in that it involves an intermediate and extraneous copy into kernel-space for no gain. But it helps illustrate the point.
让我们考虑一个同时使用
copy_from_user()和 的系统调用示例copy_to_user()。这个系统调用silly_copy()完全没有价值;它将数据从它的第一个参数复制到它的第二个参数中。这是次优的,因为它涉及到内核空间的中间和无关复制而没有任何收益。但它有助于说明这一点。
/*
* silly_copy - pointless syscall that copies the len bytes from
* ‘src' to ‘dst' using the kernel as an intermediary in the copy.
* Intended as an example of copying to and from the kernel.
*/
SYSCALL_DEFINE3(silly_copy,
unsigned long *, src,
unsigned long *, dst,
unsigned long len)
{
unsigned long buf;
/* copy src, which is in the user's address space, into buf */
if (copy_from_user(&buf, src, len))
return -EFAULT;
/* copy buf into dst, which is in the user's address space */
if (copy_to_user(dst, &buf, len))
return -EFAULT;
/* return amount of data copied */
return len;
}
Other than the catastrophic failure of not checking parameters, I'm pretty certain the last parameter of the SYSCALL_DEFINE3is missing a comma (though that would just be a typo).
除了不检查参数的灾难性失败之外,我很确定 的最后一个参数SYSCALL_DEFINE3缺少逗号(尽管这只是一个错字)。
A far better example, without having to allocate arbitrary memory, would be along the lines of:
一个更好的例子,无需分配任意内存,将沿着以下路线:
SYSCALL_DEFINE3(silly_copy,
unsigned long *, src,
unsigned long *, dst,
unsigned long, len)
{
unsigned long buf[64]; /* Buffer for chunks */
unsigned long lenleft = len; /* Remaining size */
unsigned long chunklen = sizeof(buf); /* Initial chunk length */
/* Loop handling chunk sizes */
while (lenleft > 0) {
/* Change chunk length on last chunk */
if (lenleft < chunklen) chunklen = lenleft;
/* copy src(user) to buf(kernel) then dst(user) */
if (copy_from_user(buf, src, chunklen)) return -EFAULT;
if (copy_to_user(dst, buf, chunklen)) return -EFAULT;
/* Adjust pointers and remaining size */
src += chunklen; dst += chunklen; lenleft -= chunklen;
}
/* return amount of data copied */
return len;
}
Anyone trying to implement that system call would be well advised to steer away from that particular sample in the book, although I suppose, at a bare minimum, it will give you some good kernel debugging experience :-)
任何试图实现该系统调用的人都最好避开本书中的特定示例,尽管我想,至少,它会给您一些良好的内核调试体验:-)
回答by user2264907
int init_module(void)
{
mempool_t *mempool;
struct kmem_cache *kmem_cache;
void *p0 , *p1;
kmem_cache = kmem_cache_create("Ashrama" ,100 , 0 ,SLAB_PANIC ,NULL);
mempool = mempool_create(4 , mempool_alloc_slab , mempool_free_slab , kmem_cache);
p0 = mempool_alloc(mempool, SLAB_PANIC);
p1 = mempool_alloc(mempool , SLAB_PANIC);
strcpy(p0 , "Ranjan.B.M");
strcpy(p1 , "Mithun.V");
mempool_free( p0 , mempool);
printk(KERN_ALERT"%s",p0);
printk(KERN_ALERT"%s",p1);
}

