0

user_namespaces(7)的手册页说:

由 clone(2) 创建的带有 CLONE_NEWUSER 标志的子进程以新用户命名空间中的一组完整功能开始。同样,使用 unshare(2) 创建新用户命名空间或使用 setns(2) 加入现有用户命名空间的进程在该命名空间中获得了完整的功能集。

不幸的是,手册页没有说明哪些功能集(或多个集)会受到影响:一个或多个有效上限集、允许的上限集、可继承的上限集等。所以我的问题是:哪些功能集会会受到 clone(2)、unshare(2) 和 setns(2) 的影响吗?

注意:user_namespaces(7) 的示例部分似乎表明有效和允许的功能集将被完全启用,而继承的功能则全部被丢弃。但是,没有明确的迹象表明这是实际实施的行为。此外,没有迹象表明环境上限是否受到影响;我假设边界帽不受影响,尤其是因为边界帽上只有帽下降是可能的。

4

1 回答 1

0

为了了解 setns(2) 和 unshare(2) 对功能的影响,我创建了以下小型 Python 3 脚本。确保在尝试运行它们之前安装包nsenterunshare( , ...)。pip3 install nsenter

设置(2)

# usernscaps.py: dump all capabilities sets of this process
# when entering a specific (grand)child user namespace.
from nsenter import Namespace
import sys

def dumpcaps(s):
    print(s)
    with open('/proc/self/status', 'r') as st:
        for line in st:
            if line.startswith('Cap'):
                print(line.rstrip())

if len(sys.argv) != 2:
    print('usage: usernscaps.py <PID>')
    exit(1)

dumpcaps('initial:')
try:
    with Namespace('/proc/%d/ns/user' % int(sys.argv[1]), 'user'):
        entered = True
        dumpcaps('after setns:')
except PermissionError:
    # Switching back to our original user namespace isn't allowed, so ignore the exception.
    try:
        entered
    except NameError:
        print('no permission to enter user namespace')        

作为一个普通的非特权用户,让我们创建一个新的用户命名空间,该命名空间将归我们所有,并通过睡眠进程保持打开状态(注意:我们将其置于后台):

unshare -U bash -c "readlink /proc/self/ns/user && sleep infinity" &

接下来,usernscaps.py从上面运行 Python 脚本,并使用 setns(2) 告诉它进入我们新创建的用户空间,然后最后转储能力集:

python3 usernscaps.py $(lsns -t user | grep "infinity" | awk '{ print $4 }')

即使对于我们的非特权用户和进程,这也会在 setns(2) 之后给出:

initial:
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
after setns:
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

这似乎表明 setns(2) 实际上不仅为有效上限提供了全套功能,而且还为允许的上限提供了完整的功能(这是有道理的,因为有效上限在任何时候都必须受到允许的上限的限制) . 不过,它似乎没有补足继承的上限。

克隆(2)

与之前的脚本类似,但这次是 unshare(2)。

# usernsunsharecaps.py: dump all capabilities sets of this process
# upon unsharing the user namespace.
import unshare
import sys

def dumpcaps(s):
    print(s)
    with open('/proc/self/status', 'r') as st:
        for line in st:
            if line.startswith('Cap'):
                print(line.rstrip())

dumpcaps('initial:')
unshare.unshare(unshare.CLONE_NEWUSER)
dumpcaps('after unshare:')

只需运行它python3 usernsunsharecaps.py

initial:
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
after unshare:
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

因此,这也在取消共享后在新用户命名空间内提供了完全允许有效的功能。

于 2019-12-17T20:15:23.460 回答