gpt4 book ai didi

c - 内存的 kfree 部分是否有效?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:11:41 28 4
gpt4 key购买 nike

我正在调试内存损坏问题,发现 Linux 内核似乎接受用户“释放部分缓冲区”。课本上总是教我们成对调用alloc/free。我有点迷惑不解了!所以我写了一个在 Linux 内核中运行的小测试。

char *p_buf, *p_buf2;

p_buf = kmalloc(1024, GFP_KERNEL); //alloc 1024
printk("malloc(1024) = %p\n", p_buf);

kfree(p_buf+256); //free from offset 256(equals to free 768)
printk("kfree(%p)\n", p_buf+256);

p_buf2 = kmalloc(1024-256, GFP_KERNEL); // alloc 768
printk("malloc(%d) = %p\n", 1024-256, p_buf2);

kfree(p_buf);
kfree(p_buf2);

和结果(在 Linux 3.16 上运行)

malloc(1024) = ce52b800   //alloc 1024
kfree(ce52b900) //free 768 ---(1)
malloc(768) = ce52b900 //alloc 768 ---(2)

可以看到(1)和(2)地址是一样的。这是对的吗?这是否意味着 Linux 如我所料将缓冲区分成两部分?我知道这段代码肯定是错误的,但我只想知道 Linux 内核如何处理它 - Linux 如何释放一个与 alloc 不同的地址。

提前致谢。

最佳答案

操作系统内核可能会安全地假设模块开发人员知道他们在做什么(与应用程序开发相反,应用程序开发应该永远无法损害操作系统)。

显然,Linux 已经决定(可能是出于运行时效率的原因)不检查交给kfree() 的地址是否最初由kmalloc()(一个强烈的暗示是 kfree() 的签名甚至不允许它返回错误代码)。

内核中分配的所有内存都需要在某处进行监控(最典型的是在某种 block 头中,就在它返回给你的那 block 内存之前),以便能够正确释放再次记忆。 kmalloc()某处 初始化这个(使用分配 block 的大小、用途、属于哪个实例等信息)。如果您 kfree() 一些东西不是由 kmalloc() 分配的,那么这个某处 将根本不存在并且将使内核解释任意区域内存作为某处 - 导致各种未定义的行为,最终导致内核崩溃。这种行为不当的代码迟早会崩溃,仅取决于您运行的内核中的动态量。它可能会一直有效,直到有人决定卸载您的模块,或者甚至只是因为内核内存越来越紧张。

我的(公认的旧)kfree 手册页清楚地说明了

Don't free memory not originally allocated by kmalloc or you will run into trouble.

如果你想释放缓冲区的一部分(在最后),你应该使用 krealloc(),但是总是 返回的原始指针kmalloc()

顺便说一句:找到此类误用的一种快速方法是使用定义 kmymalloc() 和 kmyfree() 的宏或函数来武装您的源代码,这些宏或函数将分配更多内存,并在开始时设置内存保护分配区域如

void  *kmymalloc(...)
unsigned long *area = kmalloc (...<size+sizeof (unsigned long)>)
*area = 0xdeadbeef;
return (void*) &(area[1]);
}
void *kmyfree(...){
unsigned long *area = *(ptr - sizeof (unsigned long));
if (*area != 0xdeadbeef)
... print a stack trace, shutdown system, or whatever
else
kfree (area)
}

关于c - 内存的 kfree 部分是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35863207/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com