我观察到以下我无法解释的现象。添加CAP_SYS_ADMIN
功能后,unshare
不再能够写入/proc/self/setgroups
.
事实上,写入这个文件需要这个能力,但这是通过改变用户命名空间来实现的。那么为什么向父进程添加功能会阻止写入该文件呢?
me@myhost:~$ unshare -r
root@myhost:~# exit
logout
me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied
me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#
顺便说一句:我正在运行内核版本为 4.4 的 Ubuntu 16.04.4 LTS,而 util-linux(包括unshare
)的版本是 2.27.1。
这里发生的是您的“取消共享”进程无权写入外部用户命名空间上的
setgroups
(anduid_maps
,gid_maps
) 文件。在该命名空间中,其中的伪文件
/proc/<PID>
将是 root 拥有的,并且好像您的有效 uid 仍然是您自己用户的,您将无权写入这些文件。您可以通过在后台运行进程(例如)并在文件运行时
sleep
检查文件的权限来轻松地可视化这一点(并且行为完全相同。)setgroups
uid_maps
gid_maps
首先,使用没有附加功能的二进制文件:
然后,让我们为其添加一些文件功能并查看所有权更改:
文件的所有权
/proc/<PID>
由 Linux 内核中的“dumpable”标志控制,该标志用于防止将信息从特权进程泄漏给非特权用户。并且考虑到您正在运行
unshare
附加功能但仍然使用非 root有效uid,通过操作系统的正常访问控制来防止对 root 拥有的这些伪文件的写访问。您可以使用prctl(2)
PR_GET_DUMPABLE
系统调用的命令检查“dumpable”标志的值。在您的描述中,
PR_SET_DUMPABLE
您还会发现:这正是您的情况,
unshare
具有文件功能的二进制文件。有趣的是,使用 root 拥有的 setuid 二进制文件
unshare
并不会遇到这个确切的问题。是的,它将清除“可转储”标志,并且其中的文件/proc/<PID>
将归根用户所有。但是考虑到在运行 setuid 二进制文件时您的有效 uid也是root,访问将被允许。在这种情况下,您最终会遇到另一个问题,这与
unshare
's 的逻辑无法处理该特定设置有关(可能与有效 uid 和实际 uid 不匹配有关):另请注意,“可转储”标志的清除是通过运行设置了文件功能的二进制文件触发的。如果您以不同的方式获得额外的功能,您可能不会遇到这个麻烦。例如,使用“环境”功能是在命名空间之外获得额外功能的好方法,同时在取消共享到新用户命名空间时仍然不会遇到麻烦。
(不幸的是,目前还没有很多关于环境功能的工具。
libcap
仅在最新的 git 中提供支持,超过 2.25 版,这是目前大多数发行版中提供的版本。capsh
相当低级,所以不容易获得它也对。有关使用 latest添加环境功能的详细信息,请参见此处。我也尝试过,但也无法真正设法在此处设置环境功能。无论如何,如果您确实需要功能,您可以研究一下,非根用户和用户命名空间在一起!)capsh
systemd-run