在对我更熟悉的操作系统进行了更深入的比较之后,我完成了自己的答案,这些操作系统的方向截然不同……
PID 随机化由 OpenBSD 推广,并于 1997 年加入。当时它追求两个主要目标:
正如我的问题中所详述的,治愈可能比疾病更糟。由于更快的 PID 重用,完全随机的 PID 可能允许远程利用漏洞,而顺序 PID 主要允许本地攻击。
附带说明一下,在理想世界中,所有这一切都不应该引起任何问题(是的,我说的是这个软件没有错误和漏洞的理想世界)。事实上,这些漏洞的根源通常在于 PID 的错误使用。Wikipedia将 PID 定义为“用于 [...] 唯一标识活动进程的数字”。所以:
PID 不是为构建临时文件名而设计的。临时文件通常是在共享的地方创建的,这意味着危险!因此,必须使用专用函数创建临时文件,这将确保以原子(不间断)方式完成三个必需的操作(检查文件是否不存在、创建文件并设置受限访问权限)。C 语言提出mkstemp()and tmpfile(),并且大多数 Unix 环境都提供mktemp命令供 shell 脚本等使用。
PID 并非旨在为随机数生成器提供种子或生成会话 ID 或 cookie。在这里,您必须再次参考您的语言或环境文档以获得正确的熵源。在 UNIX 系统上,/dev/urandom设备文件就是为此目的而存在的。
维基百科定义明确指出活动进程并非偶然。在诸如 C 之类的语言上,您一直拥有子进程的 PID,直到您wait获得它为止,但这并非适用于所有语言(例如在 shell 脚本中......),并且对于不是您的孩子的进程来说永远不会如此。在这些情况下,PID 只是一个共享资源,您应该记住这个“共享”概念意味着“危险”,因此必须确保您采取适当的措施并使用旨在满足您的情况和需求的正确功能。
Linux
Linux 内核主流从未实现 PID 随机化,但是这个特性通常通过一个面向安全的第三方补丁提供了好几年,最终决定放弃它。
大约在 2000-2001 年,有几个人试图为 Linux 内核实现 PID 随机化(示例可以在这里和那里找到),但是这些补丁都没有被内核开发团队接受,他们大多拒绝它们,因为它们是“通过默默无闻的安全”。
但是,由于随机性实际上可能会增加操作系统的全局安全态势并防止一些攻击,因此这些内核修改最终通过第三方项目公之于众:grsecurity。
这个项目始于 2001 年,为 Linux 内核带来了几个新的和高级的安全特性。它允许使用特定sysctl参数启用/禁用随机 PID kernel.grsecurity.rand_pids:. 然而,在2006 年末(我猜——我讨厌新闻线程提到没有年份的日期!)他们最终决定放弃随机 PID 功能:
grsecurity 2.1.10 今天针对 Linux 2.4.34 和 2.6.19.2 发布。此版本中的更改包括:
- 删除随机 PID 功能,因为它没有提供有用的额外安全性,并且使用 2.6 内核的 pid 位图浪费内存
OpenBSD
OpenBSD 已经启动了随机 PID 功能,它仍然出于历史目的而存在,但现在没有真正的安全范围。由应用程序自己来确保它们正确处理快速 PID 重用。
OpenBSD 的目标是鼓励良好的开发实践和彻底的代码安全审计。这就是为什么他们认为操作系统没有责任保护他们的用户免受有缺陷的应用程序的侵害。相反,应尽快检测到应用程序缺陷并在应用程序中纠正,而不是被操作系统隐藏(“我们越早破解它,我们就能越早修复”)。
作为旁注,虽然这样的断言证明了在 OpenBSD 团队直接控制下的基本操作系统是合理的,但对于第三方软件来说,这变得更有争议:
然而,在这种情况下,OpenBSD 团队假设,对于一个正确开发和审计的软件,操作系统选择的 PID 生成算法必须对软件行为没有影响(稳定性和安全性都没有)。如果某些软件容易受到利用 PID 被重用的攻击,那么由软件来纠正,而不是由操作系统来确保 PID 不会被太快地重用¹。
¹:出于好奇,OpenBSD 在 2013 年添加了一个硬编码表,用于存储最后释放的 100 个 PID,以限制低负载系统的可靠性问题。但是,这并不构成安全措施,因为随着负载的增加,它会很快变得无效,这种负载是由真正的活动引起的还是作为攻击的一部分。
自由BSD
FreeBSD 提供了一个sysctl参数,允许管理员将 PID 生成算法从顺序调整为完全随机。默认情况下是顺序的。
FreeBSD在 1999 年(FreeBSD 4)实现了随机 PID,参考 OpenBSD 并对其进行了改进,以让管理员在顺序 PID 引起的潜在问题(主要是 PID 预测)和 PID 随机化引起的潜在问题(PID 重用和资源消耗)。
事实上,FreeBSD 的设计看起来很原始,因为它实际上不是随机的 PID,而是 PID 增量,它是一个介于 1 和kern.randompid参数之间的随机值:
- 如果禁用 PID 随机化,则增量将始终为 1,
- 最多可以将此参数设置为
PID_MAX³,在这种情况下,下一个PID将完全随机选择。
默认情况下,PID 随机化被禁用(PID 是按顺序生成的)。要生效,该kern.randompid参数必须至少大于 100。
如果顺序 PID 仍然是一个问题,我个人建议将此参数设置为一个较低的值,例如几百:这应该足以限制琐碎的 PID 预测问题,同时避免由 PID 重用引起的更严重的问题。
³:对于纯粹主义者来说,它实际上是PID_MAX - 100只覆盖非保留PID范围,也可以使用特殊值来设置-1。设置参数时会立即纠正超出范围的值,sysctl因此无论如何都不会在此处造成任何损坏。