接前一篇文章:SELinux零知识学习十四、SELinux策略语言之客体类别和许可(8)
一、SELinux策略语言之客体类别和许可
4. 客体类别许可实例
(3)进程客体类别许可
与文件许可不同,许多进程许可没有直接对应到标准的Linux访问控制,因为传统的Linux没有将进程作为一个正式的客体对待。下表列出了进程客体类别许可:
许可 | 描述 |
dyntransition | 允许进程动态地转移到新的上下文中 |
execheap | 产生一个堆栈可执行体 |
execmem | 产生一个匿名的映像或可写的私有文件映像可执行体 |
execstack | 产生进程堆栈可执行体 |
fork | 派生两个进程 |
getattr | 通过/proc/[pid]/attr目录获取进程的属性 |
getcap | 获得这个进程允许的Linux能力 |
getpgid | 获取进程的组进程ID |
getsched | 获取进程的优先级 |
getsession | 获取进程的会话ID |
noatsecure | 禁用清除安全模式环境,允许进程在execve(2)上禁用glibc的安全模式特性 |
ptrace | 跟踪程序执行的父进程或子进程 |
rlimitnh | 在execve(2)上继承进程资源限制 |
setcap | 为进程设置允许的Linux能力 |
setcurrent | 设置当前的进程上下文,当进程试图执行一个动态域转换时,这是第一个检查的能力 |
setexec | 下一次调用execve(2)时覆盖默认的上下文 |
setfscreate | 允许进程设置由其创建的客体的上下文 |
setpgid | 设置进程的组进程ID |
setrlimit | 改变进程硬性资源限制 |
setsched | 设置进程的优先级 |
share | 允许与克隆的或派生的进程共享状态 |
siginh | 在execve(2)上继承信号状态 |
sigkill | 发送sigkill信号 |
sigchld | 发送sigchld信号 |
signal | 发送一个非sigkill、sigstop或sigchld的信号 |
signull | 不发送信号以测试另一个进程的存在性 |
sigstop | 发送sigstop信号 |
transition | 在execve(2)上转换到一个新的上下文 |
1)创建进程
- fork
fork许可控制进程使用fork(2)系统调用的能力,这个系统调用创建一个进程的副本,只是进程标识符和资源利用数据有所不同,派生进程的安全上下文不能改变。通常,执行一个西程序的第一步就是派生,控制进程派生的能力,限制它使用系统资源的能力,可以潜在地预防某些类型的拒绝服务攻击。
- share、siginh、rlimitnh
三个其它的许可在进程转换时控制状态的共享。share许可控制进程状态的共享,如在一个execve(2)系统调用上的文件描述符和内存地址空间。siginh许可控制信号状态的继承,包括任意挂起的信号。最后,rlimitnh许可控制从父进程那里继承的资源限制。
2)进程域类型转换
- transition、setexec、getattr
transition许可控制进程通过execve(2)系统调用从一个域转到另一个域的能力。如果允许,域转换或明确地请求时可能会自动产生一个type_transition规则,请求明确的域转换的能力是由setexec许可控制的,这个请求会向proc文件系统中写一个特定的文件,此过程在setexeccon(3)库函数中被抽象出来。为下一个请求execve(2)系统调用查看当前请求的转换的能力是由getattr许可控制的。
- noatsecure
noatsecure许可使内核在进行域转换时不设置glibc的安全模式,在安全模式下,glibc清除进程环境,包括相当多的环境变量,如LD_PRELOAD。如果不清除环境,源域可能会控制目标域的关键部分,当域转换进入更高特权域时,允许noatsecure许可是特别危险的。
- dyntransition
dyntransition许可与transition许可类似,但它是控制进程在任何时间改变域类型的能力,不仅仅是执行程序那一刻。这个许可比transition许可更危险,因为它允许起始域在新域中执行任意的代码,由于这个原因,dyntransition许可只有在目标域是起始域的一个受限的子集时可以安全地使用,否则,想要理解域改变的保护就会失败,所有授予目标域的访问权对起始域都必须能够可访问。
警告:随意使用dyntransition许可改变进程域类型会破坏标记的性质,在SELinux中,标记意味着在一个运行的系统中,创建一个客体后,它的类型将会被改变。尽管存在受信任的操作系统组件偶然改变了客体类型的可能,SELinux还是会严格控制进程的类型改变。dyntransition许可的引入打破了这种固有属性,使得所有的策略安全分析都变得即为复杂,我们强烈建议你永远都不要使用这个许可,除非你在编写用户空间客体管理器或其它SELinux扩展。
- setcurrent
dyntransition许可的setcurrent许可与transition许可的setexec许可类似,它控制请求改变进程域类型的能力,成功改变域类型需要dyntransition许可,另外还要setcurrent许可。和setexec类似,请求被写入到proc文件系统的一个特殊文件中,这个过程抽象在setcon(3)中。
3)创建文件
- setfscreatecon
与域转换类似,与文件有关的客体的安全上下文设置可以通过继承或type_transition规则进行自动创建,也可以明确地创建。通过在proc文件系统中写入一个特定的文件实现与文件有关的客体的安全上下文设置,这个过程抽象在setfscreatecon(3)库调用中,setfscreatecon许可控制产生这个明确请求的能力。与setexeccon类似,查看文件系统客体上下文请求的当前状态是由getattr许可控制的。
4)进程信号
- sigchld、sigkill、sigstop、signull和signal
向进程发送信号的权力非常大,因为它可能允许结束或停止进程。此外,信号可用于在进程间传输信息,sigchld、sigkill和sigstop许可分别控制发送SIGCHILD、SIGKILL和SIGSTOP信号的能力。signull许可控制发送空信号的能力,例如:通过传递一个0字符作为一个信号参数给kill(2)系统调用。最后,signal许可控制发送其它信号的能力。
为什么有的信号有明确的许可定义,而其它的都在常见的signal许可控制之下呢?有两个原因:SIGKILL和SIGSTOP这两个信号有明确的许可,因为它们不能由进程阻碍。SIGCHLD信号有其自己的许可主要是因为它是被正式使用的(如它经常是每个进程init时使用)。剩下的安全属性都相同,因此它们都由signal许可控制。
5)进程属性
- getsched和setsched
查询或设置调度优先级以及进程策略的能力是由getsched和setsched许可控制的。设置调度优先级和策略,特别是SCHED_FIFO策略,使用sched_setscheduler(2)系统调用可以允许进程不受限制占用CPU时间,因此,它可以用于拒绝服务攻击。
- getpgid、setpgid和getsession
进程组和会话标识符控制大部分进程的交互,包括终端处理和信号传递,getpgid和setpgid许可控制查询和设置进程组标识符。getsession许可控制进程标识符的查询。
- getcap和setcap
getcap和setcap许可控制查询和设置进程的Linux许可,要成功设置一个许可,这个许可也必须被标记了域类型的capability客体类别接受。
- setrlimit
资源限制,如核心转储的最大大小或CPU时间的最大大小,都是使用setrlimit(2)系统调用,setrlimit许可控制设置硬件资源限制的能力。
6)执行可写入内存
- execmem、execstack、execheap
正如在file客体类别的execmod许可中讨论的那样(参见SELinux零知识学习十四、SELinux策略语言之客体类别和许可(8)),执行可写入内存段的能力是许多安全事件的起源,为了帮助标记出这些事件,首先创建execmem、execstack和execheap许可,它们分别控制可执行的匿名映像、堆栈和堆的创建,许可的执行依赖于另外的软件特性(如ExecShied)和硬件特性(如NX)。
注:
- ExecShied是Red Hat开发的内核补丁,控制内存执行,并添加了其它安全特性。它被包含在所有的Fedora Core和自Red Hat Enterprise Linux 3以来的版本中。
- NX是一个硬件设置,它实现了许多ExecShied相同的目标。