设备白名单控制器

1. 描述

实现一个 cgroup 来跟踪和强制执行设备文件上的打开和 mknod 限制。设备 cgroup 将设备访问白名单与每个 cgroup 相关联。白名单条目有 4 个字段。“type” 是 (all)、c (char) 或 b (block)。“all” 表示它适用于所有类型以及所有主次号码。主次号码可以是整数或 * 表示全部。访问权限是 r (读取)、w (写入) 和 m (mknod) 的组合。

根设备 cgroup 从 rwm 到 “all” 开始。子设备 cgroup 获取父级的副本。然后,管理员可以从白名单中删除设备或添加新条目。子 cgroup 永远无法获得其父级拒绝的设备访问权限。

2. 用户界面

使用 devices.allow 添加条目,使用 devices.deny 删除条目。例如

echo 'c 1:3 mr' > /sys/fs/cgroup/1/devices.allow

允许 cgroup 1 读取和 mknod 通常称为 /dev/null 的设备。执行

echo a > /sys/fs/cgroup/1/devices.deny

将删除默认的 ‘a : rwm’ 条目。执行

echo a > /sys/fs/cgroup/1/devices.allow

将 ‘a : rwm’ 条目添加到白名单。

3. 安全性

任何任务都可以在 cgroup 之间移动自身。这显然不够,但我们可以决定在人们获得一些使用经验后充分限制移动的最佳方法。我们可能只想要求 CAP_SYS_ADMIN,至少它与 CAP_MKNOD 是一个单独的位。我们可能只想拒绝移动到不是当前 cgroup 后代的 cgroup。或者我们可能想使用 CAP_MAC_ADMIN,因为我们确实试图锁定 root。

需要 CAP_SYS_ADMIN 来修改白名单或将另一个任务移动到新的 cgroup。(再次,我们可能想要更改它)。

cgroup 可能不会被授予比 cgroup 的父级更多的权限。

4. 层次结构

设备 cgroup 通过确保 cgroup 永远不会拥有比其父级更多的访问权限来维护层次结构。每次将条目写入 cgroup 的 devices.deny 文件时,其所有子级都会从其白名单中删除该条目,并且所有本地设置的白名单条目都将重新评估。如果其中一个本地设置的白名单条目提供的访问权限多于 cgroup 的父级,则它将从白名单中删除。

示例

  A
 / \
    B

group        behavior       exceptions
A            allow          "b 8:* rwm", "c 116:1 rw"
B            deny           "c 1:3 rwm", "c 116:2 rwm", "b 3:* rwm"

如果设备在组 A 中被拒绝

# echo "c 116:* r" > A/devices.deny

它将向下传播,并在重新验证 B 的条目后,白名单条目 “c 116:2 rwm” 将被删除

group        whitelist entries                        denied devices
A            all                                      "b 8:* rwm", "c 116:* rw"
B            "c 1:3 rwm", "b 3:* rwm"                 all the rest

如果父级的异常发生更改并且不再允许本地异常,则会将其删除。

请注意,新的白名单条目不会传播

  A
 / \
    B

group        whitelist entries                        denied devices
A            "c 1:3 rwm", "c 1:5 r"                   all the rest
B            "c 1:3 rwm", "c 1:5 r"                   all the rest

当添加 c *:3 rwm

# echo "c *:3 rwm" >A/devices.allow

结果

group        whitelist entries                        denied devices
A            "c *:3 rwm", "c 1:5 r"                   all the rest
B            "c 1:3 rwm", "c 1:5 r"                   all the rest

但现在可以向 B 添加新条目了

# echo "c 2:3 rwm" >B/devices.allow
# echo "c 50:3 r" >B/devices.allow

甚至

# echo "c *:3 rwm" >B/devices.allow

一旦设备 cgroup 有子项,将 ‘a’ 写入 devices.allow 或 devices.deny 来允许或拒绝所有操作将不可能。

4.1 层次结构 (内部实现)

设备 cgroup 在内部使用行为 (ALLOW, DENY) 和异常列表来实现。内部状态使用相同的用户界面控制,以保持与以前的仅白名单实现的兼容性。删除或添加将减少对设备访问的异常将向下传播到层次结构中。对于每个传播的异常,将基于当前父级的访问规则重新评估有效规则。