假设从内核 2.6 开始。
我观察系统上所有正在运行的进程。
孩子的PID总是大于父母的PID吗?
是否有可能出现“反转”的特殊情况?
答案1
不,原因很简单,PID 可以具有最大数值。如果一个进程具有最高的 PID,则它派生的子进程不能具有更大的 PID。给孩子一个较低的 PID 的另一种选择是完全失败fork()
,这不会很有成效。
PID 按顺序分配,在使用最高的 PID 后,系统会重新使用(空闲)较低的 PID,因此在其他情况下您也可以为子进程获取较低的 PID。
我的系统( )上默认的最大 PID/proc/sys/kernel/pid_max
只是 32768,所以达到环绕发生的条件并不难。
$ echo $$
27468
$ bash -c 'echo $$'
1296
$ bash -c 'echo $$'
1297
如果您的系统随机分配 PID(就像 OpenBSD 似乎做的那样)而不是连续(如 Linux),有两种选择。要么在整个可能的 PID 空间上进行随机选择,在这种情况下,很明显子进程的 PID 可能低于父进程的。或者,子进程的 PID 将从大于父进程 PID 的值中随机选择,这平均会将其置于父进程 PID 和最大值之间。递归分叉的进程将很快达到最大值,我们将处于与上面提到的相同的点:新的分叉需要使用较低的 PID 才能成功。
答案2
此外,还存在使用内核通知和分叉自己以避免被进程表扫描检测到的潜在安全漏洞;如果做得正确,您的进程将具有较低的 PID,并且进程工具看不到有问题的进程。
http://cve.circl.lu/cve/CVE-2018-1121
procps-ng,procps 很容易受到通过竞争条件隐藏的进程的影响。由于内核的 proc_pid_readdir() 按升序返回 PID 条目,因此占用高 PID 的进程可以使用 inotify 事件来确定何时扫描进程列表,并使用 fork/exec 来获取较低的 PID,从而避免枚举。非特权攻击者可以通过利用读取 /proc/PID 条目时的竞争条件来隐藏 procps-ng 实用程序中的进程。此漏洞影响 procps 和 procps-ng 直至版本 3.3.15,较新的版本也可能受到影响。