早期linux上信任状模型非常简单,就是"超级用户对普通用户"模型。普通用户的很多操作需要root权限,这通过setuid实现。如果程序编写不 好,就可能被攻击者利用,获得系统的控制权。使用能力机制(capability)减小这种风险。系统管理员为了系统的安全可以剥夺root用户的能力, 这样即使root用户也将无法进行某些操作。而这个过程又是不可逆的,也就是说如果一种能力被删除,除非重新启动系统,否则即使root用户也无法重新添 加被删除的能力。
其定义在 <linux/capability.h> 中。
对设备驱动编写者有意义的权能如下:
CAP_DAC_OVERRIDE /*越过在文件和目录上的访问限制(数据访问控制或 DAC)的能力。*/
CAP_NET_ADMIN /*进行网络管理任务的能力, 包括那些能够影响网络接口的任务*/
CAP_SYS_MODULE /*加载或去除内核模块的能力*/
CAP_SYS_RAWIO /*进行 "raw"(裸)I/O 操作的能力. 例子包括存取设备端口或者直接和 USB 设备通讯*/
CAP_SYS_ADMIN /*截获的能力, 提供对许多系统管理操作的途径*/
CAP_SYS_TTY_CONFIG /*执行 tty 配置任务的能力*/
在进行一个特权操作之前, 一个设备驱动应当检查调用进程有合适的能力,
检查是通过 capable 函数来进行的(定义在 <linux/sched.h> )
范例如下:
if (! capable (CAP_SYS_ADMIN)
capable 通过检查进程的有效能力集task->cap_effective的能力位,判断进程是否具有相应的能力.
每个进程的任务结构中有三个和能力有关的位图变量,列出如下(在include/linux/sched.h中):
kernel_cap_t cap_effective, cap_inheritable, cap_permitted; //能力机制
unsigned keep_capabilities:1; //表示是否保持能力值
内核通过导出系统调用capget, capset - set/get capabilities of thread(s),使用户可以在用户态管理进程的能力。