"许可被拒绝"从非特权子进程中的进程替换FIFO读取

时间:2017-06-02 18:17:19

标签: linux bash unix permissions

在Linux 3.19内核上使用bash 4.4观察以下内容:

# in reality, this may access files "nobody" isn't allowed
get_a_secret() { printf '%s\n' "This is a secret"; }

# attach a process substitution reading the secret to FD 10
exec 10< <(get_a_secret)

# run a less-privileged program that needs the secret, passing it the file descriptor.
chpst -u nobody:nobody -- cat /dev/fd/10

...或更短/更简单:

chpst -u nobody:nobody -- cat <(get_a_secret)

要么以类似于以下的方式失败:

cat: /proc/self/fd/10: Permission denied

所以,这个问题有两个分支:

  • 这里发生了什么?

  • 是否有办法获得所需的行为(将秘密读取的能力传递给单个子进程,该进程以不会将该秘密持续暴露给运行为&的其他进程的方式调用#34; nobody&#34;)没有将FIFO的输出暴露给其他进程?

(是的,我很清楚我需要锁定ptrace和/proc/*/mem以防止另一个进程正在运行,因为&#34; nobody&#34;不会将秘密拉出正在阅读的客户端;那就是说,我可以做的事情,以及(2)当流程只在任何潜在的攻击者控制的可执行文件被调用之前运行时,允许任何以nobody运行的进程在该进程的整个持续时间内将秘密从/proc/*/environ中拉出来。)

1 个答案:

答案 0 :(得分:1)

以下解决方法可以避免此问题:

exec 10< <(get_a_secret)
chpst -u nobody:nobody -- sh -c 'cat <&10'

请注意重定向被写为<&10 - 不是 </dev/fd/10</proc/self/fd/10(在提供/dev/fd的平台上) - 在没有平台的情况下这个工具,bash将其重写为fdup2()电话。

对行为进行解释的答案(可能是允许接受FD号作为输入的程序在读取方上行动的解决方法?)将能够取代这一个。 :)