linux capability介绍
最早之前,linux对任务权限分为privileged processes(UID等于0,属于超级用户或者root用户)和unprivileged processes(UID非0)。privileged processes拥有系统的所有权限,而unprivileged processes拥有部分权限(根据进程凭证,比如effective UID, effective GID,and supplementary group list)。
Linux自2.2版本以后,加入了capabilities功能,将这些特权分为不同的种类,比如
- CAP_KILL:拥有kill进程的权限
- CAP_SETFCAP:拥有配置文件capabulities属性的权限
- CAP_SYS_BOOT:运行reboot和kexec_load的权限
- CAP_SYS_MODULE:模块相关操作的权限
(更多介绍:参考文档3中“Capabilities list”介绍)
内核细分的这些权限,不再根据超级用户/普通用户来划分归属,而是可以由用户自由配置(配置还是要超级用户权限滴),即使普通用户也可以做某些之前超级用户才可以执行的任务(比如reboot)。同时capabilities可以细分到线程,支持子进程或者创建线程继承capabilities属性。
每个线程拥有四个capability sets:
(1)Permitted(pP):规定该线程的capabilities能力的全集,即表示线程能够使用的能力的集合。它并不使能线程的capabilities,而是作为一个规定。
(2)Effective(pE):使能该线程的capabilities能力。当线程进行某个特权操作时,系统会检查effective对应位是否有效。如有效,则允许执行。
(3)Inheritable(pI):线程通过execve(2) 执行新命令时,新命令集成的capabilities能力。
(4)bounding set(X):关闭线程的capabilities能力。(此项在capabilities的man文档中并未和上面三个并列,但是在patch中提及,属于capabilitiy sets一员)
举例来说,
某线程设置Permitted:CAP_KILL,CAP_SETFCAP和CAP_SYS_BOOT,那么此线程最大能拥有这些权限。
如果想让它拥有重启系统的权限(CAP_SYS_BOOT),那么Effective设置CAP_SYS_BOOT即可(另外两项可以不设置)。如果想要拥有Permitted定义以外的权限,比如CAP_WAKE_ALARM ,那么Effective会设置失败。
如果希望execve(2)执行新的命令有重启系统权限,那么设置Inheritable:CAP_SYS_BOOT即可。
(更多介绍:参考文档3中“Thread capability sets”介绍)
同时文件也可以拥有capabilities权限,Permitted(fP),Effective(fE)和Inheritable(fI)。
使用execve(2)执行的新命令继承权限遵循:
pP' = (X & fP) | (pI & fI) pI' = pI pE' = (fE ? pP' : 0) X is unchanged