从/proc/获取Linux中的可执行文件名称并检测它是否被截断

从/proc/获取Linux中的可执行文件名称并检测它是否被截断

可执行文件名称为linux,可以通过多种方式读取。

  1. 通过读取 /proc/[pid]/comm,其中包含一个在达到 16 个字符或 TASK_COMM_LEN 后被截断的字符串。
  2. 通过读取 /proc/[pid]/cmdline 其中包含与参数一起使用的命令行。

还有其他方法,例如读取 /proc/[pid]/stat 或 /proc/[pid]/status,但它们与 1 类似。

对于第 1 点,过程(5)手册页说:

可执行文件的文件名,位于括号中。长度超过 TASK_COMM_LEN (16) 个字符(包括终止空字节)的字符串将被静默截断。无论可执行文件是否被换出,这都是可见的。


我发现 3 个进程不匹配并突出显示它们(现在在我的系统上):

  1. PID 7610
  2. PID 38193
  3. PID 37030

考虑这些情况:

  1. PID 7610:
  • 的内容/proc/7610/commWeb Content
  • 但内容/proc/7610/cmdline/opt/firefox-developer-edition/firefox-bin-contentproc-childID17-isForBrowser-prefsLen7837-prefMapSize238232-parentBuildID20201215185920-appdir/opt/firefox-developer-edition/browser4080truetab
  1. PID 38193:
  • 的内容/proc/38193/commzyxwvutsrqponml
  • 但内容/proc/38193/cmdline/ramdisk/abcdefghijklmnopqrstuvwxyz./zyxwvutsrqponmlkjihgfedcba

我可以通过编程方式看到和\u0000之间的内容,我将其替换为。ramdisk/abcdefghijklmnopqrstuvwxyz./zyxwvutsrqponmlkjihgfedcba\s

  1. PID 37030
  • 的内容/proc/37030/commkworker/3:1-xfs-reclaim/sda2
  • 的内容/proc/37030/cmdline为空。

  • 在情况 1 中,我们看到 cmdline 和 comm 完全不同。
  • 在情况 2 中,我们看到 cmdline 显示了整个命令,但 comm 被截断为 15 个字符。
  • 在情况 3 中,我们看到 cmdline 为空,但 comm 并未按预期被截断。

文件 comm 如何包含“kworker/3:1-xfs-reclaim/sda2”而不被截断为 15 个位置(+ \n 为 16)?

我如何知道它是否真的被截断,就像第 2 点的情况一样?

答案1

唯一可靠的方法是 via /proc/PID/exe,即使可执行文件已被删除,或者它根本就不存在(例如执行使用memfd_create()viafexecve()execveat(AT_EMPTY_PATH).

/proc/PID/comm和都/proc/PID/cmdline可以很容易地被进程本身伪造(前者通过prctl(PR_SET_NAME),后者仅通过覆盖argv[]字符串)。

文件如何comm包含kworker/3:1-xfs-reclaim/sda2内容而不被截断为 15 个位置(+\n为 16)?

这是一个内核线程,而不是用户态进程,并且不同规则申请 ;-)

相关内容