我观察到以下我无法解释的现象。添加该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:~#
顺便一提:我运行的是 Ubuntu 16.04.4 LTS,内核版本为 4.4,util-linux(包括 )的版本unshare
为 2.27.1。
答案1
这里发生的情况是您的“取消共享”进程无权写入setgroups
(和uid_maps
,gid_maps
)文件外部的用户命名空间。
在该命名空间中,其中的伪文件/proc/<PID>
将由 root 拥有,并且就好像您的有效 uid 仍然是您自己的用户的一样,您将无权写入这些文件。
您可以通过在后台运行一个进程(例如)并在运行时sleep
检查文件的权限(并且行为完全相同)来轻松地可视化这一点。setgroups
uid_maps
gid_maps
首先,使用没有附加功能的二进制文件:
$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$
然后,让我们向其添加一些文件功能并查看所有权更改:
$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$
文件的所有权/proc/<PID>
由 Linux 内核中的“可转储”标志控制,该标志用于防止将信息从特权进程泄漏给非特权用户。
考虑到您正在运行unshare
附加功能,但仍然使用非 root有效的uid,通过操作系统的正常访问控制来阻止对 root 拥有的这些伪文件的写访问。
PR_GET_DUMPABLE
您可以使用以下命令检查“dumpable”标志的值prctl(2)系统调用。
在描述中PR_SET_DUMPABLE
您还会发现:
通常,该标志设置为 1。但是,
/proc/sys/fs/suid_dumpable
在以下情况下,它会重置为文件中包含的当前值(默认值为 0):[...]
- 该进程执行 (
execve(2)
) 一个具有文件功能的程序(参见capabilities(7)
),但前提是所获得的允许能力超过了该过程已经允许的能力。
这正是您的情况,unshare
具有文件功能的二进制文件。
有趣的是,使用 root 拥有的 setuid 二进制文件unshare
不会遇到这个问题。是的,它将清除“可转储”标志,并且其中的文件/proc/<PID>
将归 root 所有。但考虑到你的有效uid是还root 当运行 setuid 二进制文件时,将允许访问。
在这种情况下,您最终会遇到不同的问题,这与unshare
的逻辑无法处理该特定设置有关(可能与有效 uid 和实际 uid 不匹配有关):
$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$
另请注意,“可转储”标志的清除是通过运行设置了文件功能的二进制文件触发的。如果您以不同的方式获得额外的功能,您可能不会遇到这个麻烦。例如,使用“环境”功能是在命名空间之外获取其他功能的好方法,同时在取消共享到新用户命名空间时仍然不会遇到麻烦。
(不幸的是,目前还没有很多围绕环境功能的工具。libcap
仅在最新的 git 版本 2.25 中提供支持,这是目前大多数发行版中提供的版本。它的capsh
级别相当低,因此获取它并不容易也对吧。这里有关使用最新capsh
添加环境功能的详细信息。我也尝试过,systemd-run
但也无法真正设法在那里设置环境功能。无论如何,如果您确实需要功能、非 root 用户和用户命名空间,那么您需要研究一下!)