gpt4 book ai didi

c - brk/sbrk 的不安全/遗留问题是什么?

转载 作者:太空狗 更新时间:2023-10-29 17:24:44 26 4
gpt4 key购买 nike

我在很多地方(musl 邮件列表、macOS 论坛等)听说 brk()sbrk() 是不安全的。这些地方很多要么根本不解释,要么解释的很模糊。例如,this链接指出“这些功能从根本上被破坏了”,并继续说 mallocsbrk 子系统完全被破坏,它们破坏了堆,等等。

我的问题是:为什么会这样?如果 malloc 以这样的方式使用,即它分配了一 block 内存,其中 sbrk 足够大以平息或大大减少进一步分配的需要,那么 sbrkbrk 使用起来绝对安全吗?

这是我对 sbrkbrk 的实现:

sbrk:

#include <unistd.h>
#include <stddef.h>

void *sbrk(intptr_t inc)
{
intptr_t curbrk = syscall(SYS_brk, NULL);

if( inc == 0 ) goto ret;

if( curbrk < 0 ) return (void *)-1;

curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;
}

brk:

#include <unistd.h>

intptr_t brk(void *ptr)
{
if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;
}

最佳答案

现实在很大程度上取决于实现,但这里有一些要素:

不安全

brk/sbrk 的发明是为了允许进程从系统请求更多内存,并在单个连续段中释放它。因此,它们被许多 mallocfree 实现使用。问题是,当它返回一个唯一的段时,当多个模块(同一进程的)直接使用它时,事情会出错。由于竞争条件,它在多线程进程中变得更糟。假设有 2 个线程要添加新内存。他们将使用 sbrk(0) 查看当前的顶部地址,查看相同的地址,使用 brksbrk 请求新内存,并且由于竞争条件,两者将使用相同的内存。

即使在单线程进程中,某些mallocfree 实现也假设它们只被允许使用低级s/brk接口(interface),并且任何其他代码都应该使用它们。在那种情况下,如果他们内部维护的中断段的图像不再是假定值,事情就会出错。他们必须猜测该段的某些部分是“保留”供其他用途使用的,这可能会破坏释放任何内存的能力。

因此,用户代码不应直接使用brk/sbrk,而应仅依赖于malloc/free。当且仅当您正在编写标准库的实现,包括 malloc/realloc/calloc/free,你可以安全地使用brk/sbrk

遗产

在现代系统上,mmap 可以更好地使用虚拟内存管理。您可以根据需要使用任意数量的动态内存段,它们之间没有交互。因此,在现代系统上,除非您有使用 brk/sbrk 进行内存分配的特定需求,否则您应该使用 mmap

便携性

brksbrk 的 FreeBSD 引用指出:

The brk() and sbrk() functions are legacy interfaces from before the advent of modern virtual memory management.

及以后:

BUGS: Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will result in non-portable program behavior.

关于c - brk/sbrk 的不安全/遗留问题是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55367809/

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