cgroup devices 子系统分析

一.     devices子系统总体结构

cgroup devices子系统通过为每个cgroup维护一个设备访问权限链表管理和控制cgroup中进程对设备文件读写访问和设备文件节点创建。

从功能角度分析,devices子系统主要分为三个部分:子系统初始化接口、子系统文件接口和子系统访问控制接口。

子系统初始化接口在cgroup初始化各个子系统时被调用,功能是继承或者创建一个设备访问权限链表,标识cgroup中对各个系统设备访问权限等信息;文件接口的功能是用户进程修改cgroup目录下devices子系统配置文件内容后,更新devices子系统的配置;访问控制接口主要是检查设备的权限,该类接口提供系统访问设备文件或创建设备节点时检查操作的合法性,实现访问控制。

二.     devices子系统初始化接口

devices子系统为每个cgroup维护一个设备访问权限链表管理和控制cgroup中进程对设备文件读写访问和设备文件节点创建,初始化接口在cgroup初始化devices子系统时最重要的工作就是继承或者创建访问权限链表。


2.1  数据结构和接口

devices子系统的核心数据结构是structdev_whitelist_item,具体定义如下。

该数据结构标识一个设备权限的实体,major和minor说明主次设备号,type说明设备类型,而access具体制定了该设备的访问权限。每个设备的权限实体通过list链接成链表。

另一个数据结构是struct dev_cgroup,具体定义如下。

该数据结构第一个成员是strcut cgroup_subsys_state类型变量,初始化函数返回该成员的地址。第二个成员即指向设备权限链表,通过它开始链表的操作。

devices定义了一些函数操作该链表。

2.2  初始化流程

devices子系统实现了cgroup子系统接口structcgroup_subsys devices_subsys:

devcgroup_create接口在cgroup初始化devices子系统时完成初始化工作。该函数首先分配一个dev_cgroup,并初始化其中的whitelist链表。之后判断调用devcgroup_create的cgroup是否是最上层的cgroup。如果是,即cgroup->parent为空,则需要创建新的设备权限链表。链表只有一个元素,首先分配一个struct dev_whitelist_item,初始化各个变量使其默认该cgroup可以访问所有设备,并且拥有所有权限,最后将该实体加入到whitelist链表上。如果cgroup是一个子cgroup,那么devcgroup_create仅仅拷贝父cgroup的devices子系统链表到whitelist上,不做任何操作。

三.     devices子系统文件接口

在cgroup目录下有三个文件:devices.allow、devices.deny和devices.list。分别用来启用、禁用和列出cgroup支持的设备。cgroup中有规定:在树形结构的cgroup中,如果父cgroup禁用了某设备,那么子cgroup无权启用该设备;而子cgroup可以禁用父cgroup支持的设备和权限。devices子系统实现的三个文件接口如下,其实allow和deny是只写文件,list是只读文件。

3.1 device.allow接口和device.deny接口

用户进程写device.allow和device.deny文件内核都是触发devcgroup_access_write函数。如果写device.allow文件,即启用设备,是往whitelist添加设备item;如果写device.deny文件,即禁用设备,是从whitelist删除设备的item。

向whitelist上添加item前要检查该设备是否可以被启用,即遍历链表看看是否已经有标识该设备权限的item,且权限是禁用。如果是,则操作失败;如果没有该设备的item,则添加到whitlelist中。

禁用设备时函数根据主次设备号、设备类型遍历whitelist查找是否有该设备,如果有就删除该item。

3.2 device.list接口

用户进程读device.list文件触发函数devcgroup_seq_read,函数遍历whitlelist并且格式化输出每个item的主次设备号、类型和访问权限。

四.     devices子系统访问控制接口

devices子系统向内核提供访问控制接口,限制内核对设备的读写权限和创建设备节点的功能。核心思想就是在内核验证设备访问权限时时候增加判断,决定操作的成功。提供的接口声明如下。

devcgroup_inode_permission函数用于判断设备的读写权限,再访问一个设备文件前执行用于控制内核对设备文件的读写操作。devcgroup_inode_mknod函数判断一个设备是否允许创建设备节点,在虚拟文件系统创建设别文件节点时调用,可以实现对设备节点创建的权限控制。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章