/proc/*/cmdline 是世界可读的有什么原因吗?

/proc/*/cmdline 是世界可读的有什么原因吗?

也许我今天还没有喝足够的咖啡,但我不记得或想不出任何理由为什么/proc/PID/cmdline应该让世界可读——毕竟不是/proc/PID/environ

使其只能由用户(当然也可能是组和 root)读取可以防止作为命令行参数输入的密码被意外泄露。

当然会影响其他用户运行ps等等htop- 但这是一件好事,对吧?这就是不让世界可读的关键所在。

答案1

我怀疑主要的,也许是唯一的原因是历史性的——/proc/.../cmdline最初是世界可读的,所以为了向后兼容,它仍然保持这种方式。cmdline1992年12月2日发布的0.98.6中添加,模式444;变更日志说

     - /proc filesystem extensions.  Based on ideas (and some code) by
       Darren Senn, but mostly written by yours truly.  More about that
       later.

我不知道“后来”是什么时候;据我所知,达伦·森的想法已经消失在时间的迷雾中。

environ是向后兼容性论证的一个有趣的反例:它一开始是文字可读的,但在 1.1.85 中变成只有其所有者可读。我还没有找到相关的变更日志,所以我不知道原因是什么。

/proc/${pid}(包括)的整体可访问性和可见性/proc/${pid}/cmdline可以控制使用 的proc挂载hidepid选项,这是在内核3.3版本中添加。 mountgid选项可用于授予对特定组的完全访问权限,例如这样监控进程仍然可以看到一切,而无需以 root 身份运行。

答案2

进程的命令行在 Unix 中一直被认为是公共信息,并且始终可以通过ps(1)命令。相反,过程的环境从来都不是这样的公共信息。

在最初的 Unix 实现中,有一个 setuid 可执行文件,它以调试器的方式直接从内核的实时内存中ps打开并提取所有信息。 Linux很早就/dev/mem支持类似 plan9 的文件系统,并且/procps文件系统,并且被实现为一个简单的非固定的程序只是打开并读取/proc/<pid>/stat和 之类的文件/proc/<pid>/cmdline。由于它们既是用于获取该信息的常规内核/用户界面,又是解析ps(yuck)输出的 shell 友好替代方案,因此它们不可能,并且比ps.

当然,它会影响其他正在运行的用户ps等等htop- 但这是一件好事,对吧?这就是不让世界可读的关键所在。

不,这不是一件好事。除了违反标准(请参阅上面的链接)之外,这将使系统在没有 root 权限的情况下无法调试,而且这种安全优势充其量只是虚幻的。 (请注意,在 Unix 发明时,通过默默无闻和言论自由限制实现的安全性还没有像今天这样流行。)

你不必想象这样的 Linux 系统会是什么样子——已经有了 Android,hidepid对于它的实际用户来说,非 root 系统是一个令人讨厌的黑匣子(以所有可能的方式锁定,而不仅仅是用) ,但对于外部攻击者和数据收集者来说,它并没有比典型的 Debian 或 Slackware 桌面或服务器更强大。

答案3

仅适用于那些想要阻止用户看到 root 用户命令行的人:

使用 hidepid=1 选项挂载 /proc 文件系统:

sudo mount -o remount,rw,nosuid,nodev,noexec,relatime,hidepid=1 /proc

https://man7.org/linux/man-pages/man5/proc.5.html,搜索 hidepid。

hidepid 参数值接受三个值:

  • 0: 这是默认的。每个用户都可以读取存储在进程目录中的所有世界可读的文件。
  • 1:根进程目录仍列在 /proc 中,但用户无法访问。用户只能访问自己的进程目录。这可以保护 cmdline、sched 或 status 等敏感文件免遭非 root 用户的访问。此设置不会影响实际的文件权限。
  • 2:进程文件对于非 root 用户是不可见的。进程的存在可以通过其他方式得知,但其有效用户ID(UID)和组ID(GID)是隐藏的。

相关内容