请考虑在 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
因此,这个问题有两个分支:
这是怎么回事?
有没有办法获得所需的行为(将读取 secret 的能力传递给正在调用的单个子进程,而不会将该 secret 持续暴露给以“无人”身份运行的其他进程) )而不将 FIFO 的输出暴露给其他进程?
(是的,我很清楚我需要锁定 ptrace 和 /proc/*/mem
以防止另一个以“无人”身份运行的进程在读取 secret 时将其从客户端中提取出来;也就是说,这是(1)我可以做的事情,(2)当进程仅在调用任何潜在攻击者控制的可执行文件之前运行时,比允许任何进程以 nobody
运行来从 /proc/*/environ
中提取 secret 要少暴露。在该过程的整个持续时间内)。
最佳答案
以下解决方法可以避免此问题:
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 编号作为输入的程序在读取端执行操作?)取代这个。 :)
关于linux - "Permission denied"从非特权子进程中的进程替换 FIFO 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44335166/