我观察到以下我无法解释的现象。添加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:~#
Run Code Online (Sandbox Code Playgroud)
顺便说一句:我正在运行内核版本为 4.4 的 Ubuntu 16.04.4 LTS,并且 util-linux(包括unshare
)的版本为 2.27.1。
fil*_*den 11
这里发生的事情是您的“取消共享”进程无权写入外部用户命名空间上的setgroups
(和uid_maps
, gid_maps
)文件。
在该命名空间中, 中的伪文件/proc/<PID>
将由 root 拥有,并且就好像您的有效 uid 仍然是您自己用户的 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
$
Run Code Online (Sandbox Code Playgroud)
然后,让我们为其添加一些文件功能并查看所有权更改:
$ 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
$
Run Code Online (Sandbox Code Playgroud)
文件的所有权/proc/<PID>
由 Linux 内核中的“可转储”标志控制,该标志用于防止信息从特权进程泄露给非特权用户。
并且考虑到您正在unshare
使用附加功能运行但仍然使用非 root有效uid,因此通过操作系统的正常访问控制阻止了对这些由 root 拥有的伪文件的写访问。
您可以使用prctl(2)系统调用的PR_GET_DUMPABLE
命令检查“dumpable”标志的值。
在PR_SET_DUMPABLE
您的描述中,您还会发现:
通常,此标志设置为 1。但是
/proc/sys/fs/suid_dumpable
,在以下情况下,它会重置为文件中包含的当前值(默认值为 0):[...]
- 进程执行 (
execve(2)
) 一个具有文件能力的程序(请参阅capabilities(7)
),但前提是获得的允许能力超过了进程已经允许的能力。
这正是您的情况,unshare
具有文件功能的二进制文件。
有趣的是,使用 root 拥有的 setuid 二进制文件unshare
不会遇到这个确切的问题。是的,它将清除“可转储”标志,并且其中的文件/proc/<PID>
将由 root 拥有。但是考虑到在运行 setuid 二进制文件时您的有效 uid也是root,将允许访问。
在这种情况下,您最终会遇到另一个问题,这与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$
Run Code Online (Sandbox Code Playgroud)
另请注意,“可转储”标志的清除是通过运行设置了文件功能的二进制文件触发的。如果您以不同的方式获得额外的功能,您可能不会遇到这个问题。例如,使用“环境”功能是在命名空间之外获得额外功能的好方法,同时在取消共享到新用户命名空间时仍然不会遇到问题。
(不幸的是,目前还没有很多围绕环境功能的工具。libcap
仅在最新的 git 中提供支持,过去版本 2.25,这是目前大多数发行版中提供的版本。capsh
相当低级,因此获取它并不容易也可以。有关使用最新的添加环境功能的详细信息,请参阅此处capsh
。我也尝试过,systemd-run
但也无法真正设法在那里设置环境功能。无论如何,如果您确实需要功能,非- root 用户和用户命名空间在一起!)
归档时间: |
|
查看次数: |
1286 次 |
最近记录: |