06-文件能力
39.3.2 文件能力
如果一个文件拥有相关的能力集,那么这些集合会被用来确定赋给执行这个文件的进程的能力。文件能力集包括下面3个。
- 许可的:在exec()调用中可以将这组能力添加到进程的许可集中,不管进程的既有能力是什么。
- 有效的:这个只有一位。如果被启用了,那么在exec()调用中,进程的新许可集中启用的能力在进程的新有效集中也会被启用。如果文件有效位被禁用了,那么在exec()执行完之后,进程的新有效集在一开始是空的。
- 可继承的:这个集合将与进程的可继承集取掩码来确定在执行exec()之后进程的许可集中启用的能力集。
第39.5节详细描述了在exec()调用中如何使用文件能力。
许可和可继承文件能力原来称为强制的能力和允许的能力。现在那些术语已经过时了,但它们仍然能够提供一些有用的信息。许可的文件能力是那些在exec()调用中被强制添加到进程的许可集中的能力,不管进程的既有能力是什么。可继承的文件能力是那些在exec()调用中允许进入进程的许可集中的能力,前提是在进程的可继承能力集中也启用了那些能力。 与文件相关的能力是存储在名为security.capability的安全扩展特性(参见16.1节)中的,更新这个扩展特性需要具备CAP_SETFCAP能力。
| 能 力 | 允 许 进 程 | | :----- | :----- | :----- | :----- | | CAP_AUDIT_CONTROL | (自Linux 2.6.11起)启用和禁用内核审计日志、修改审计的过滤规则、读取审计状态和过滤规则 | | CAP_AUDIT_WRITE | (自Linux 2.6.11起)向内核审计日志写入记录 | | CAP_CHOWN | 修改文件的用户ID(所有者)或将文件的组ID修改为不包含进程的一个组(chown()) | | CAP_DAC_OVERRIDE | 绕过文件读取、写入和执行权限检查(DAC是discretionary access control的缩写);读取/proc/PID中cwd、exe和root符号链接的内容 | | CAP_DAC_READ_SEARCH | 绕过文件读取权限检查以及目录读取和执行的权限检查 | | CAP_FOWNER | 忽略那些平时要求进程的文件系统用户ID与文件的用户ID匹配的操作(chmod(), utime())的权限检查;设置任意文件的i-node标记;设置和修改任意文件的ACL;在删除文件(unlink(), rmdir(), rename())时忽略目录粘滞位的效果;在open()和fcntl(F_SETFL)中为任意文件指定O_NOATIME标记 | | CAP_FSETID | 修改文件时使内核不关闭set-user-ID和set-group-ID位(write(), truncate());为那些组ID与进程的文件系统组ID或补充组ID不匹配的文件启用set-group-ID位 | | CAP_IPC_LOCK | 覆盖内存加锁限制(mlock(), mlockall(), shmctl(SHM_LOCK), shmctl(SHM_UNLOCK));使用shmget() SHM_HUGETLB标记和mmap() MAP_HUGETLB标记 | | CAP_IPC_OWNER | 绕过操作System V IPC对象的权限检查 | | CAP_KILL | 绕过发送信号(kill(), sigqueue())的权限检查 | | CAP_LEASE | (自Linux 2.4起)在任意文件上建立租赁关系(fcntl(F_SETLEASE)) | | CAP_LINUX_IMMUTABLE | 设置附加和不可变的i-node标记 | | CAP_MAC_ADMIN | (自Linux 2.6.25起)配置或修改强制访问控制(MAC)的状态(一些Linux安全模块实现了这个能力) | | CAP_MAC_OVERRIDE | (自Linux 2.6.25起)覆盖MAC(一些Linux安全模块实现了这个能力) | | CAP_MKNOD | (自Linux 2.4起)使用mknod()创建设备 | | CAP_NET_ADMIN | 执行各种网络相关的操作(如设置特权socket选项、启用组播、配置网络接口、修改路由表) | | CAP_NET_BIND_SERVICE | 绑定到特权socket端口 | | CAP_NET_BROADCAST | (未使用)执行socket广播和监听组播 | | CAP_NET_RAW | 使用原始和包socket | | CAP_SETGID | 随意修改进程组ID(setgid(), setegid(), setregid(),setresgid(), setfsgid(), setgroups(), initgroups());在通过UNIX domain socket(SCM_CREDENTIALS)传递验证信息时伪造组ID | | CAP_SETFCAP | (自Linux 2.6.24起)设置文件能力 | | CAP_SETPCAP | 在不支持文件能力时将进程的许可集中的能力授予其他进程(包括自己)或删除其他进程(包括自己)许可集中的能力;在支持文件能力时将进程的能力边界集中的所有能力都添加到自己的可继承集中,删除边界集中的能力以及修改securebits标记 | | CAP_SETUID | 随意修改进程用户ID(setuid(), seteuid(), setreuid(),setresuid(), setfsuid());在通过UNIX domain socket(SCM_CREDENTIALS)传递验证信息时伪造用户ID | | CAP_SYS_ADMIN | 在打开文件的系统调用中(如open(),shm_open(), pipe(), socket(), accept(), exec(), acct(), epoll_create())超出/proc/sys/fs/file-max限制;执行各种系统管理操作,包括quotactl()(控制磁盘限额)、mount()和umount(), swapon()和swapoff(), pivot_root(), sethostname() 和setdomainname();执行各种syslog(2)操作;覆盖RLIMIT_NPROC资源限制(fork());调用lookup_dcookie();设置trusted和security扩展特性;在任意System V IPC对象上执行IPC_SET 和 IPC_RMID操作;在通过UNIX domain socket(SCM_CREDENTIALS)传递验证信息时伪造进程ID;使用ioprio_set()来分配IOPRIO_CLASS_RT调度类;使用TIOCCONS ioctl();在clone()和unshare()中使用CLONE_NEWNS标记;执行KEYCTL_CHOWN和KEYCTL_SETPERM keyctl()操作;管理random(4)设备;各种特定于设备的操作 | | CAP_SYS_BOOT | 使用reboot()重启系统;调用kexec_load() | | CAP_SYS_CHROOT | 使用chroot()设置进程根目录 | | CAP_SYS_MODULE | 加载和卸载内核模块(init_module(), delete_module(), create_module()) | | CAP_SYS_NICE | 提高nice值(nice(), setpriority());修改任意进程的nice值(setpriority());设置调用进程的SCHED_RR 和 SCHED_FIFO实时调度策略;重置SCHED_RESET_ON_FORK标记;设置任意进程的调度策略和优先级(sched_setscheduler(), sched_setparam());设置任意进程的I/O调度类和优先级(ioprio_set());设置任意进程的CPU亲和力(sched_setaffinity());使用migrate_pages()将任意进程迁移到任意节点以及允许进程被迁移到任意节点;对任意进程应用move_pages();在mbind() 和 move_pages()中使用MPOL_MF_MOVE_ALL标记 | | CAP_SYS_PACCT | 使用acct()启用或禁用进程记账 | | CAP_SYS_PTRACE | 使用ptrace()跟踪任意进程;访问任意进程的/proc/PID/environ;对任意进程应用get_robust_list() | | CAP_SYS_RAWIO | 使用iopl() 和 ioperm()在I/O端口上执行操作;访问/proc/kcore;打开/dev/mem和/dev/kmem | | CAP_SYS_RESOURCE | 使用文件系统上的预留空间;使用ioctl()调用控制ext3 journaling;覆盖磁盘限额限制;提高硬资源限制(setrlimit());覆盖RLIMIT_NPROC资源限制(fork());将System V消息队列的/proc/sys/kernel/msgmnb限制提高msg_qbytes;绕过由/proc/sys/fs/mqueue下各个文件定义的各种POSIX消息队列限制 | | CAP_SYS_TIME | 修改系统时钟(settimeofday(), stime(), adjtime(), adjtimex());设置硬件时钟 | | CAP_SYS_TTY_CONFIG | 使用vhangup()执行终端或伪终端的虚拟挂起 |