Pla*_*ton 58 linux process fork ulimit
最近我一直在挖掘有关 GNU/Linux 进程的信息,我遇到了臭名昭著的 fork 炸弹:
:(){ : | :& }; :
Run Code Online (Sandbox Code Playgroud)
理论上,它应该无限复制自己,直到系统耗尽资源......
但是,我已经尝试在CLI Debian和GUI Mint发行版上进行测试,它似乎对系统影响不大。是的,创建了大量进程,一段时间后我在控制台消息中阅读了如下内容:
bash: fork: 资源暂时不可用
bash: fork: 重试: 没有子进程
但是一段时间后,所有进程都会被杀死,一切都恢复正常。我读过ulimit为每个用户设置了最大进程数,但我似乎无法将其提高到很远。
什么是针对叉形炸弹的系统保护?为什么在一切都冻结或至少滞后很多之前它不会自我复制?有没有办法用叉子炸弹真正使系统崩溃?
Hko*_*oof 87
您可能有一个使用 systemd 的 Linux 发行版。
Systemd为每个用户创建一个cgroup,一个用户的所有进程都属于同一个cgroup。
Cgroups 是一种 Linux 机制,用于设置系统资源的限制,例如最大进程数、CPU 周期、RAM 使用率等。这是一个不同的、更现代的资源限制层ulimit(使用getrlimit()系统调用)。
如果您运行systemctl status user-<uid>.slice(代表用户的 cgroup),您可以看到该cgroup 中允许的当前和最大任务数(进程和线程)。
$ systemctl status user-$UID.slice
? user-22001.slice - UID 22001 的用户切片
加载:加载
插入:/usr/lib/systemd/system/user-.slice.d
??10-defaults.conf
活跃:自 EEST 2018-09-10 17:36:35 Mon 开始活跃;1 周 3 天前
任务:17(限制:10267)
内存:616.7M
默认情况下,systemd 允许每个用户的最大任务数是“系统范围最大值”( sysctl kernel.threads-max) 的33% ;这通常相当于约 10,000 个任务。如果要更改此限制:
在 systemd v239 及更高版本中,用户默认值是通过TasksMax=设置的:
/usr/lib/systemd/system/user-.slice.d/10-defaults.conf
Run Code Online (Sandbox Code Playgroud)
要调整特定用户的限制(将立即应用并存储在 /etc/systemd/system.control 中),请运行:
systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
Run Code Online (Sandbox Code Playgroud)
在systemctl edit这里也可以使用覆盖单元设置(例如)的常用机制,但它们需要重新启动。例如,如果您想更改每个用户的限制,您可以创建/etc/systemd/system/user-.slice.d/15-limits.conf.
在 systemd v238 及更早版本中,用户默认值是通过UserTasksMax= in设置的/etc/systemd/logind.conf。更改该值通常需要重新启动。
有关此的更多信息:
Jos*_*hua 13
无论如何,这不会再使现代 Linux 系统崩溃。
它创建了大量进程,但在进程空闲时并没有真正消耗那么多 CPU。在现在用完 RAM 之前,您用完了进程表中的插槽。
如果您不像 Hkoof 指出的那样受 cgroup 限制,以下更改仍会导致系统宕机:
:(){ : | :& : | :& }; :
Run Code Online (Sandbox Code Playgroud)
早在 90 年代,我不小心对自己释放了其中一个。我无意中在包含 fork() 命令的 C 源文件上设置了执行位。当我双击它时,csh 尝试运行它而不是像我想要的那样在编辑器中打开它。
即便如此,它也没有使系统崩溃。Unix 足够强大,您的帐户和/或操作系统将具有进程限制。相反,它会变得非常缓慢,任何需要启动进程的东西都可能会失败。
幕后发生的事情是进程表填满了试图创建新进程的进程。如果其中一个进程终止(由于进程表已满导致 fork 出错,或者由于绝望的操作员试图恢复其系统的健全性),其他进程之一将愉快地 fork 一个新的进程来填充虚空。
“分叉炸弹”基本上是一种无意中自我修复的进程系统,其任务是保持进程表完整。阻止它的唯一方法是以某种方式一次杀死它们。