![linux 有没有什么措施防御 fork 炸弹?](https://linux22.com/image/1317940/linux%20%E6%9C%89%E6%B2%A1%E6%9C%89%E4%BB%80%E4%B9%88%E6%8E%AA%E6%96%BD%E9%98%B2%E5%BE%A1%20fork%20%E7%82%B8%E5%BC%B9%EF%BC%9F.png)
#include <unistd.h>
int main(int argc, char* argv[]) {
while(1)
{
fork();
}
}
我在我的 Linux 上运行这个程序,终端上没有任何输出,操作系统似乎死机了。Linux 对这种可能耗尽内存的程序有什么保护措施吗?
答案1
答案2
是的,尽管您的系统可能未默认启用此功能。setrlimit
系统调用定义系统限制——包括每个用户的进程数。
让我们首先在内核 API 中查看它(因为您提到了“linux”):您可以使用 setrlimit 的手册页,它将告诉您执行类似以下操作
#include <sys/resource.h>
...
struct rlimit r;
rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);
这会将每个用户的最大进程数(RLIMIT_NPROC
)设置为 40(软限制)和 50(硬限制)。
现在,从 shell 中,如果您使用 bash,则可以使用ulimit
内置命令:
ulimit -u
29089
您可以通过将其作为参数传递来设置限制:
ulimit -u 100
ulimit --help
将显示您可以设置的其他几个限制(您可能感兴趣的一个限制是用户使用的最大文件描述符数量)。
答案3
这取决于您想在用户级别还是系统级别使用它。在用户级别ulimit
(或其他 shell 的相应命令)将是最简单的解决方案。
然而,在系统层面,有一些机制可以防止恶意用户(或只是不使用 ulimit)停止系统。Linux cgroups 机制可以限制每个组的资源。您可以(通过pam_systemd
机制)强制用户会话处于特定组中。这还有其他好处,例如 CPU 调度程序。
答案4
由于这里最新的答案已有 3 年多了,我想指出,较新的内核(自 4.3 以来)已明确支持通过新的“PID 子系统”防止 fork 炸弹。(见https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865c和https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2)