linux - "Permission denied"从非特权子进程中的进程替换 FIFO 读取

标签 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

因此,这个问题有两个分支:

  • 这是怎么回事?

  • 有没有办法获得所需的行为(将读取 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/

相关文章:

linux - 调用另一个脚本以在目录中的每个文件上执行的脚本

linux - bash 中的 while 循环多个条件有什么问题

bash - 包含函数的 map 未将正确的结果返回到stdout

c - 用C程序查找HP-UX上的进程使用的虚拟内存?

python - TCP 和 UNIX 套接字之间有区别吗?

unix - 根据从另一个文件中选择的标题从文件中提取列

java - crontab 在 linux 上运行 java shell 脚本

linux - awk 命令创建单个列的 sha2 并粘贴到新文件中

linux - 从 NFS 安装文件夹开始更改 bash 脚本中的网络 ip

r - 将参数从对 bash 脚本的调用传递到 Rscript