6.7. MAC策略入口函数参考

6.7.1. 通用的模块入口函数

6.7.1.1. mpo_init

void fsfuncmpo_init(conf); 
struct mac_policy_conf *conf;
 
参数说明锁定
confMAC 策略定义 

策略加载事件。当前进程正持有策略链表上的互斥锁,因此是非睡眠的,对其他内核子系统的调用也须慎重。 如果需要在策略初始化阶段进行可能造成睡眠阻塞的存储分配操作,可以将它们放在一个单独的模块 SYSINIT() 过程中集中进行。

6.7.1.2. mpo_destroy

void fsfuncmpo_destroy(conf); 
struct mac_policy_conf *conf;
 
参数说明锁定
confMAC 策略定义 

策略加载事件。必须持有策略链表互斥锁,因此需要慎重行事。

6.7.1.3. mpo_syscall

int fsfuncmpo_syscall(td,  
 call,  
 arg); 
struct thread *td;
int call;
void *arg;
 
参数说明锁定
td调用线程 
call策略特有的系统调用编号 
arg系统调用参数的指针 

该入口函数提供策略复用的系统调用,这样策略模块不需要为其向用户进程提供的每一个额外服务而注册专用的系统调用。 由应用程序提供的策略注册名字来确定提供其所申请服务的特定策略,所有参数将通过该入口函数传递给被调用的策略。 当实现新服务时,安全模块必须在必要时通过 MAC 框架调用相应的访问控制检查机制。 比方说,假如一个策略实现了某种额外的信号功能,那么它应该调用相关的信号访问控制检查,以接受 MAC 框架中注册的其他策略的检查。

注意:

不同的模块需要并发地手动进行copyin()拷贝系统调用数据。

6.7.1.4. mpo_thread_userret

void fsfuncmpo_thread_userret(td); 
struct thread *td;
 
参数说明锁定
td返回线程 

使用该入口函数,策略模块能够在线程返回用户空间时(系统调用返回、异常返回等等)进行 MAC 相关的处理工作。 使用动态进程标记的策略需要使用该入口函数,因为在处理系统调用的过程中,并不是在任意时刻都能申请到进程锁的; 进程的标记可能表示传统的认证信息、进程历史记录或者其他数据。为使用该入口函数,对进程信任状所作的修改 可能被存放在 p_label ,该域受一个进程级自旋锁的保护;接下来,设置线程级的TDF_ASTPENDING 标志位和进程级的PS_MACPENDM标志位,表明将调度一个对 userret 入口函数的调用。通过该入口函数, 策略可以在相对简单的同步上下文中创建信任状的替代品。策略编程人员必须清楚,需要保证与调度一个 AST 相关的事件执行次序, 同时所执行的 AST 可能很复杂,而且在处理多线程应用程序时可能被重入。

6.7.2. 操作标记

6.7.2.1. mpo_init_bpfdesc_label

void fsfuncmpo_init_bpfdesc_label(label); 
struct label *label;
 
参数说明锁定
label将被应用的新标记 

为一个新近实例化的 bpfdesc(BPF 描述子)初始化标记。可以睡眠。

6.7.2.2. mpo_init_cred_label

void fsfuncmpo_init_cred_label(label); 
struct label *label;
 
参数说明锁定
label将被初始化的新标记 

为一个新近实例化的用户信任状初始化标记。可以睡眠。

6.7.2.3. mpo_init_devfsdirent_label

void fsfuncmpo_init_devfsdirent_label(label); 
struct label *label;
 
参数说明锁定
label将被应用的新标记 

为一个新近实例化的 devfs 表项初始化标记。可以睡眠。

6.7.2.4. mpo_init_ifnet_label

void fsfuncmpo_init_ifnet_label(label); 
struct label *label;
 
参数说明锁定
label将被应用的新标记 

为一个新近实例化的网络接口初始化标记。可以睡眠。

6.7.2.5. mpo_init_ipq_label

void fsfuncmpo_init_ipq_label(label,  
 flag); 
struct label *label;
int flag;
 
参数说明锁定
label将被应用的新标记 
flag睡眠/不睡眠 malloc(9); 参见下文 

为一个新近实例化的 IP 分片重组队列初始化标记。其中的flag域可能取M_WAITOKM_NOWAIT之一,用来避免在该初始化调用中因为 malloc(9) 而进入睡眠。IP 分片重组队列的分配操作通常是在 对性能有严格要求的环境下进行的,因此实现代码必须小心地避免睡眠和长时间的操作。IP 分片重组队列分配操作失败时上述入口函数将失败返回。

6.7.2.6. mpo_init_mbuf_label

void fsfuncmpo_init_mbuf_label(flag,  
 label); 
int flag;
struct label *label;
 
参数说明锁定
flag睡眠/不睡眠 malloc(9); 参见下文 
label将被初始化的策略标记 

为一个新近实例化的 mbuf 数据包头部(mbuf)初始化标记。 其中的flag的值可能取M_WAITOKM_NOWAIT之一, 用来避免在该初始化调用中因为 malloc(9) 而进入睡眠。Mbuf 头部的分配操作常常在对性能有严格要求的环境下被频繁执行, 因此实现代码必须小心地避免睡眠和长时间的操作。上述入口函数在 Mbuf 头部分配操作失败时将失败返回。

6.7.2.7. mpo_init_mount_label

void fsfuncmpo_init_mount_label(mntlabel,  
 fslabel); 
struct label *mntlabel;
struct label *fslabel;
 
参数说明锁定
mntlabel将被初始化的mount 结构策略标记 
fslabel将被初始化的文件系统策略标记 

为一个新近实例化的 mount 点初始化标记。可以睡眠。

6.7.2.8. mpo_init_mount_fs_label

void fsfuncmpo_init_mount_fs_label(label); 
struct label *label;
 
参数说明锁定
label将被初始化的标记 

为一个新近加载的文件系统初始化标记。可以睡眠。

6.7.2.9. mpo_init_pipe_label

void fsfuncmpo_init_pipe_label(label); 
struct label*label;
 
参数说明锁定
label将被填写的标记 

为一个刚刚实例化的管道初始化安全标记。可以睡眠。

6.7.2.10. mpo_init_socket_label

void fsfuncmpo_init_socket_label(label,  
 flag); 
struct label *label;
int flag;
 
参数说明锁定
label将被初始化的新标记 
flagmalloc(9) flags 

为一个刚刚实例化的套接字初始化安全标记。其中的 flag 域的值必须被指定为 M_WAITOKM_NOWAIT之一,以避免在该初始化程中使用可能睡眠的malloc(9)

6.7.2.11. mpo_init_socket_peer_label

void fsfuncmpo_init_socket_peer_label(label,  
 flag); 
struct label *label;
int flag;
 
参数说明锁定
label将被初始化的新标记 
flagmalloc(9) flags 

为刚刚实例化的套接字对等体进行标记的初始化。其中的 flag 域的值必须被指定为 M_WAITOKM_NOWAIT 之一,以避免在该初始化程中使用可能睡眠的 malloc(9)

6.7.2.12. mpo_init_proc_label

void fsfuncmpo_init_proc_label(label); 
struct label *label;
 
参数说明锁定
label将被初始化的新标记 

为一个刚刚实例化的进程初始化安全标记。可以睡眠。

6.7.2.13. mpo_init_vnode_label

void fsfuncmpo_init_vnode_label(label); 
struct label *label;
 
参数说明锁定
label将被初始化的新标记 

为一个刚刚实例化的 vnode 初始化安全标记。可以睡眠。

6.7.2.14. mpo_destroy_bpfdesc_label

void fsfuncmpo_destroy_bpfdesc_label(label); 
struct label *label;
 
参数说明锁定
labelbpfdesc 标记 

销毁一个 BPF 描述子上的标记。在该入口函数中,策略应当释放所有在内部分配与 label 相关联的存储空间,以便销毁该标记。

6.7.2.15. mpo_destroy_cred_label

void fsfuncmpo_destroy_cred_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的标记 

销毁一个信任状上的标记。在该入口函数中,策略应当释放所有在内部分配的与 label 相关联的存储空间,以便销毁该标记。

6.7.2.16. mpo_destroy_devfsdirent_label

void fsfuncmpo_destroy_devfsdirent_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的标记 

销毁一个 devfs 表项上的标记。在该入口函数中,策略应当释放所有在内部分配的与 label 相关联的存储空间,以便销毁该标记。

6.7.2.17. mpo_destroy_ifnet_label

void fsfuncmpo_destroy_ifnet_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的标记 

销毁与一个已删除接口相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label 相关联的存储空间,以便销毁该标记。

6.7.2.18. mpo_destroy_ipq_label

void fsfuncmpo_destroy_ipq_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的标记 

销毁与一个 IP 分片队列相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label 相关联的存储空间,以便销毁该标记。

6.7.2.19. mpo_destroy_mbuf_label

void fsfuncmpo_destroy_mbuf_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的标记 

销毁与一个 Mbuf 相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label 相关联的存储空间,以便销毁该标记。

6.7.2.20. mpo_destroy_mount_label

void fsfuncmpo_destroy_mount_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的 Mount 点标记 

销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 mntlabel 相关联的存储空间,以便销毁该标记。

6.7.2.21. mpo_destroy_mount_label

void fsfuncmpo_destroy_mount_label(mntlabel,  
 fslabel); 
struct label *mntlabel;
struct label *fslabel;
 
参数说明锁定
mntlabel将被销毁的 Mount 点标记 
fslabelFile system label being destroyed> 

销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 mntlabelfslabel 相关联的存储空间,以便销毁该标记。

6.7.2.22. mpo_destroy_socket_label

void fsfuncmpo_destroy_socket_label(label); 
struct label *label;
 
参数说明锁定
label将被销毁的套接字标记 

销毁与一个套接字相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label 相关联的存储空间,以便销毁该标记。

6.7.2.23. mpo_destroy_socket_peer_label

void fsfuncmpo_destroy_socket_peer_label(peerlabel); 
struct label *peerlabel;
 
参数说明锁定
peerlabel将被销毁的套接字对等实体标记 

销毁与一个套接字相关联的对等实体标记。在该入口函数中,策略应当释放所有在内部分配的,与 label 相关联的存储空间,以便销毁该标记。

6.7.2.24. mpo_destroy_pipe_label

void fsfuncmpo_destroy_pipe_label(label); 
struct label *label;
 
参数说明锁定
label管道标记 

销毁一个管道的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label 相关联的存储空间,以便销毁该标记。

6.7.2.25. mpo_destroy_proc_label

void fsfuncmpo_destroy_proc_label(label); 
struct label *label;
 
参数说明锁定
label进程标记 

销毁一个进程的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label 相关联的存储空间,以便销毁该标记。

6.7.2.26. mpo_destroy_vnode_label

void fsfuncmpo_destroy_vnode_label(label); 
struct label *label;
 
参数说明锁定
label进程标记 

销毁一个 vnode 的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label 相关联的存储空间,以便销毁该标记。

6.7.2.27. mpo_copy_mbuf_label

void fsfuncmpo_copy_mbuf_label(src,  
 dest); 
struct label *src;
struct label *dest;
 
参数说明锁定
src源标记 
dest目标标记 

src 中的标记信息拷贝到 dest中。

6.7.2.28. mpo_copy_pipe_label

void fsfuncmpo_copy_pipe_label(src,  
 dest); 
struct label *src;
struct label *dest;
 
参数说明锁定
src源标记 
dest目标标记 

src 中的标记信息拷贝至 dest

6.7.2.29. mpo_copy_vnode_label

void fsfuncmpo_copy_vnode_label(src,  
 dest); 
struct label *src;
struct label *dest;
 
参数说明锁定
src源标记 
dest目标标记 

src 中的标记信息拷贝至 dest

6.7.2.30. mpo_externalize_cred_label

int fsfuncmpo_externalize_cred_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.31. mpo_externalize_ifnet_label

int fsfuncmpo_externalize_ifnet_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.32. mpo_externalize_pipe_label

int fsfuncmpo_externalize_pipe_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.33. mpo_externalize_socket_label

int fsfuncmpo_externalize_socket_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.34. mpo_externalize_socket_peer_label

int fsfuncmpo_externalize_socket_peer_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.35. mpo_externalize_vnode_label

int fsfuncmpo_externalize_vnode_label(label,  
 element_name,  
 sb,  
 *claimed); 
struct label *label;
char *element_name;
struct sbuf *sb;
int *claimed;
 
参数说明锁定
label将用外部形式表示的标记 
element_name需要外部表示标记的策略的名字 
sb用来存放标记的文本表示形式的字符buffer 
claimed如果可以填充element_data 域,则其数值递增 

根据传入的标记结构,产生一个以外部形式表示的标记。 一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。 目前的MAC实现方案将依次调用策略的相应入口函数,因此, 具体策略的实现代码,需要在填写sb之前,先检查element_name中指定的名字。 如果element_name中的内容与你的策略名字不相符,则直接返回0。 仅当转换标记数据的过程中出现错误时,才返回非0值。 一旦策略决定填写element_data,递增*claim的数值。

6.7.2.36. mpo_internalize_cred_label

int fsfuncmpo_internalize_cred_label(label,  
 element_name,  
 element_data,  
 claimed); 
struct label *label;
char *element_name;
char *element_data;
int *claimed;
 
参数说明锁定
label将被填充的标记 
element_name需要内部表示标记的策略的名字 
element_data需要被转换的文本数据 
claimed如果数据被正确转换,则其数值递增 

根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。 目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求, 因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字, 来确定是否需要转换element_data中存放的数据。 类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。

6.7.2.37. mpo_internalize_ifnet_label

int fsfuncmpo_internalize_ifnet_label(label,  
 element_name,  
 element_data,  
 claimed); 
struct label *label;
char *element_name;
char *element_data;
int *claimed;
 
参数说明锁定
label将被填充的标记 
element_name需要内部表示标记的策略的名字 
element_data需要被转换的文本数据 
claimed如果数据被正确转换,则其数值递增 

根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。 目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求, 因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字, 来确定是否需要转换element_data中存放的数据。 类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。

6.7.2.38. mpo_internalize_pipe_label

int fsfuncmpo_internalize_pipe_label(label,  
 element_name,  
 element_data,  
 claimed); 
struct label *label;
char *element_name;
char *element_data;
int *claimed;
 
参数说明锁定
label将被填充的标记 
element_name需要内部表示标记的策略的名字 
element_data需要被转换的文本数据 
claimed如果数据被正确转换,则其数值递增 

根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。 目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求, 因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字, 来确定是否需要转换element_data中存放的数据。 类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。

6.7.2.39. mpo_internalize_socket_label

int fsfuncmpo_internalize_socket_label(label,  
 element_name,  
 element_data,  
 claimed); 
struct label *label;
char *element_name;
char *element_data;
int *claimed;
 
参数说明锁定
label将被填充的标记 
element_name需要内部表示标记的策略的名字 
element_data需要被转换的文本数据 
claimed如果数据被正确转换,则其数值递增 

根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。 目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求, 因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字, 来确定是否需要转换element_data中存放的数据。 类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。

6.7.2.40. mpo_internalize_vnode_label

int fsfuncmpo_internalize_vnode_label(label,  
 element_name,  
 element_data,  
 claimed); 
struct label *label;
char *element_name;
char *element_data;
int *claimed;
 
参数说明锁定
label将被填充的标记 
element_name需要内部表示标记的策略的名字 
element_data需要被转换的文本数据 
claimed如果数据被正确转换,则其数值递增 

根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。 目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求, 因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字, 来确定是否需要转换element_data中存放的数据。 类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。

6.7.3. 标记事件

策略模块使用MAC 框架提供的“标记事件”类入口函数,对内核对象的标记进行操作。策略模块将感兴趣的被标记内核对象的相关生命周期事件 注册在恰当的入口点上。对象的初始化、创建和销毁事件均提供了钩子点。在某些对象上还可以实现重新标记,即,允许用户进程改变对象上的标记值。 对某些对象可以实现其特定的对象事件,比如与 IP 重组相关的标记事件。一个典型的被标记对象在其生命周期中将拥有下列入口函数:

标记初始化 o (对象相关的等待) \ 标记创建 o \ 重新标记事件, o--<--. 各种对象相关的, | | 访问控制事件 ~-->--o \ 标记销毁 o

使用标记初始化入口函数,策略可以以一种统一的、与对象使用环境无关的方式设置标记的初始值。 分配给一个策略的缺省 slot 值为0,这样不使用标记的策略可能并不需要执行专门的初始化操作。

标记的创建事件发生在将一个内核数据结构同一个真实的内核对象相关联(内核对象实例化)的时刻。 例如,在真正被使用之前,在一个缓冲池内已分配的 mbuf 数据结构,将保持为“未使用”状态。 因此,mbuf 的分配操作将导致针对该 mbuf 的标记初始化操作,而 mbuf 的创建操作则被推迟到该 mbuf 真正与一个数据报相关联的时刻。 通常,调用者将会提供创建事件的上下文,包括创建环境、创建过程中涉及的其他对象的标记等。例如,当一个套接字创建一个 mbuf 时, 除了新创建的 mbuf 及其标记之外,作为创建者的套接字与其标记也被提交给策略检查。 不提倡在创建对象时就为其分配内存的原因有两个:创建操作可能发生在对性能有严格要求的内核接口上; 而且,因为创建调用不允许失败,所以无法报告内存分配失败。

对象特有的事件一般不会引发其他的标记事件,但是在对象上下文发生改变时,策略使用它们可以对相关标记进行修改或更新操作。 例如,在MAC_UPDATE_IPQ 入口函数之内,某个 IP 分片重组队列的标记可能会因为队列中接收了新的 mbuf 而被更新。

访问控制事件将在后续章节中详细讨论。

策略通过执行标记销毁操作,释放为其分配的存储空间或维护的状态,之后内核才可以重用或者释放对象的内核数据结构。

除了与特定内核对象绑定的普通标记之外,还有一种额外的标记类型:临时标记。这些标记用于存放由用户进程提交的更新信息。 它们的初始化和销毁操作与其他标记一样,只是创建事件,MAC_INTERNALIZE,略有不同: 该函数接受用户提交的标记,负责将其转化为内核表示形式。

6.7.3.1. 文件系统对象标记事件操作

6.7.3.1.1. mpo_associate_vnode_devfs
void fsfuncmpo_associate_vnode_devfs(mp,  
 fslabel,  
 de,  
 delabel,  
 vp,  
 vlabel); 
struct mount *mp;
struct label *fslabel;
struct devfs_dirent *de;
struct label *delabel;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
mpDevfs 挂载点 
fslabelDevfs 文件系统标记 (mp->mnt_fslabel) 
deDevfs 目录项 
delabelde 相关联的策略标记 
vpde 相关联的 vnode 
vlabelvp 相关联的策略标记 

根据参数 de 传入的 devfs 目录项及其标记信息,为一个新近创建的 devfs vnode 填充标记(vlabel)。

6.7.3.1.2. mpo_associate_vnode_extattr
int fsfuncmpo_associate_vnode_extattr(mp,  
 fslabel,  
 vp,  
 vlabel); 
struct mount *mp;
struct label *fslabel;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
mp文件系统挂载点 
fslabel文件系统标记 
vp将被标记的 vnode 
vlabelvp 相关联的策略标记 

从文件系统扩展属性中读取 vp 的标记。成功,返回 0。 不成功,则在 errno 指定的相应的错误编码。 如果文件系统不支持扩展属性的读取操作,则可以考虑将 fslabel 拷贝至 vlabel

6.7.3.1.3. mpo_associate_vnode_singlelabel
void fsfuncmpo_associate_vnode_singlelabel(mp,  
 fslabel,  
 vp,  
 vlabel); 
struct mount *mp;
struct label *fslabel;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
mp文件系统挂载点 
fslabel文件系统标记 
vp将被标记的 vnode 
vlabelvp 相关联的策略标记 

在非多重标记文件系统上,使用该入口函数,根据文件系统标记,fslabel, 为 vp 设置策略标记。

6.7.3.1.4. mpo_create_devfs_device
void fsfuncmpo_create_devfs_device(dev,  
 devfs_dirent,  
 label); 
dev_t dev;
struct devfs_dirent *devfs_dirent;
struct label *label;
 
参数说明锁定
devdevfs_dirent 对应的设备 
devfs_dirent将被标记的 Devfs 目录项 
label将被填写的 devfs_dirent 标记 

为传入设备新建的 devfs_dirent 填写标记。该函数将在设备文件系统加载、重构或添加新设备时被调用。

6.7.3.1.5. mpo_create_devfs_directory
void fsfuncmpo_create_devfs_directory(dirname,  
 dirnamelen,  
 devfs_dirent,  
 label); 
char *dirname;
int dirnamelen;
struct devfs_dirent *devfs_dirent;
struct label *label;
 
参数说明锁定
dirname新建目录的名字 
namelen字符串 dirname 的长度 
devfs_dirent新建目录在 Devfs 中对应的目录项 

为传入目录参数的新建 devfs_dirent 填写标记。该函数将在加载、重构设备文件系统,或者添加一个需要指定目录结构的新设备时被调用。

6.7.3.1.6. mpo_create_devfs_symlink
void fsfuncmpo_create_devfs_symlink(cred,  
 mp,  
 dd,  
 ddlabel,  
 de,  
 delabel); 
struct ucred *cred;
struct mount *mp;
struct devfs_dirent *dd;
struct label *ddlabel;
struct devfs_dirent *de;
struct label *delabel;
 
参数说明锁定
cred主体信任状 
mpdevfs 挂载点 
dd链接目标 
ddlabeldd 相关联的标记 
de符号链接项 
delabelde 相关联的策略标记 

为新近创建的 devfs(5) 符号链接项填写标记(delabel)。

6.7.3.1.7. mpo_create_vnode_extattr
int fsfuncmpo_create_vnode_extattr(cred,  
 mp,  
 fslabel,  
 dvp,  
 dlabel,  
 vp,  
 vlabel,  
 cnp); 
struct ucred *cred;
struct mount *mp;
struct label *fslabel;
struct vnode *dvp;
struct label *dlabel;
struct vnode *vp;
struct label *vlabel;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
mount文件系统挂载点 
label文件系统标记 
dvp父目录 vnode 
dlabeldvp 相关联的策略标记 
vp新创建的 vnode 
vlabelvp 相关联的策略标记 
cnpvp中的子域名字 

vp 的标记写入文件扩展属性。成功,将标记填入 vlabel, 并返回 0。否则,返回对应的错误编码。

6.7.3.1.8. mpo_create_mount
void fsfuncmpo_create_mount(cred,  
 mp,  
 mnt,  
 fslabel); 
struct ucred *cred;
struct mount *mp;
struct label *mnt;
struct label *fslabel;
 
参数说明锁定
cred主体信任状 
mp客体;将被挂载的文件系统 
mntlabel将被填写的 mp 的策略标记 
fslabel将被挂载到 mp 的文件系统的策略标记。 

为传入的主体信任状所创建的挂载点填写标记。该函数将在文件系统挂载时被调用。

6.7.3.1.9. mpo_create_root_mount
void fsfuncmpo_create_root_mount(cred,  
 mp,  
 mntlabel,  
 fslabel); 
struct ucred *cred;
struct mount *mp;
struct label *mntlabel;
struct label *fslabel;
 

为传入的主体信任状所创建的挂载点填写标记。该函数将在挂载根文件系统时,mpo_create_mount; 之后被调用。

6.7.3.1.10. mpo_relabel_vnode
void fsfuncmpo_relabel_vnode(cred,  
 vp,  
 vnodelabel,  
 newlabel); 
struct ucred *cred;
struct vnode *vp;
struct label *vnodelabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
vp将被重新标记的 vnode 
vnodelabelvp 现有的策略标记 
newlabel将取代vnodelabel的新(可能只是部分)标记 

根据传入的新标记和主体信任状,更新参数 vnode 的标记。

6.7.3.1.11. mpo_setlabel_vnode_extattr
int fsfuncmpo_setlabel_vnode_extattr(cred,  
 vp,  
 vlabel,  
 intlabel); 
struct ucred *cred;
struct vnode *vp;
struct label *vlabel;
struct label *intlabel;
 
参数说明锁定
cred主体信任状 
vp写出标记所对应的 vnode 
vlabelvp的策略标记 
intlabel将被写入磁盘的标记 

将参数 intlabel 给出的标记信息写入指定 vnode 的扩展属性。 该函数被 vop_stdcreatevnode_ea 所调用。

6.7.3.1.12. mpo_update_devfsdirent
void fsfuncmpo_update_devfsdirent(devfs_dirent,  
 direntlabel,  
 vp,  
 vnodelabel); 
struct devfs_dirent *devfs_dirent;
struct label *direntlabel;
struct vnode *vp;
struct label *vnodelabel;
 
参数说明锁定
devfs_dirent客体;devfs 目录项 
direntlabel将被更新的devfs_dirent的策略标记 
vp父 vnode已锁定
vnodelabelvp的策略标记 

根据所传入的 devfs vnode 标记,对 devfs_dirent 的标记进行更新。 重新标记一个 devfs vnode 的操作成功之后,将调用该函数来确认标记的改变,如此,即使相应的 vnode 数据结构被内核回收重用, 也不会丢失标记的新状态。另外,在 devfs 中新建一个符号链接时,紧接着mac_vnode_create_from_vnode, 也将调用该函数,对 vnode 标记进行初始化操作。

6.7.3.2. IPC 对象标记事件操作

6.7.3.2.1. mpo_create_mbuf_from_socket
void fsfuncmpo_create_mbuf_from_socket(so,  
 socketlabel,  
 m,  
 mbuflabel); 
struct socket *so;
struct label *socketlabel;
struct mbuf *m;
struct label *mbuflabel;
 
参数说明锁定
socket套接字套接字锁定 WIP
socketlabelsocket 的策略标记  
m客体;mbuf 
mbuflabel将被填写的 m 的策略标记  

根据传入的套接字标记为新创建的mbuf头部设置标记。 每当套接字产生一个新的数据报或者消息,并将其存储在参数 mbuf 中时,将调用该函数。

6.7.3.2.2. mpo_create_pipe
void fsfuncmpo_create_pipe(cred,  
 pipe,  
 pipelabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe 的策略标记  

根据传入的主体信任状参数,设置新建管道的标记。每当一个新管道被创建,该函数将被调用。

6.7.3.2.3. mpo_create_socket
void fsfuncmpo_create_socket(cred,  
 so,  
 socketlabel); 
struct ucred *cred;
struct socket *so;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状不可改变
so客体;将被标记的套接字 
socketlabel将被填写的 so 的标记 

根据传入的主体信任状参数,设置新建套接字的标记。每当新建一个套接字,该函数将被调用。

6.7.3.2.4. mpo_create_socket_from_socket
void fsfuncmpo_create_socket_from_socket(oldsocket,  
 oldsocketlabel,  
 newsocket,  
 newsocketlabel); 
struct socket *oldsocket;
struct label *oldsocketlabel;
struct socket *newsocket;
struct label *newsocketlabel;
 
参数说明锁定
oldsocket监听套接字 
oldsocketlabeloldsocket 的策略标记  
newsocket新建套接字 
newsocketlabelnewsocket 的策略标记  

根据 listen(2) 套接字 oldsocket, 为新建 accept(2) 的套接字 newsocket,设置标记。

6.7.3.2.5. mpo_relabel_pipe
void fsfuncmpo_relabel_pipe(cred,  
 pipe,  
 oldlabel,  
 newlabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *oldlabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
oldlabelpipe 的当前策略标记  
newlabel将为pipe 设置的新的策略标记  

pipe设置新标记newlabel

6.7.3.2.6. mpo_relabel_socket
void fsfuncmpo_relabel_socket(cred,  
 so,  
 oldlabel,  
 newlabel); 
struct ucred *cred;
struct socket *so;
struct label *oldlabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状不可改变
so客体;套接字 
oldlabelso 的当前标记  
newlabel将为socket 设置的新标记  

根据传入的标记参数,对套接字的当前标记进行更新。

6.7.3.2.7. mpo_set_socket_peer_from_mbuf
void fsfuncmpo_set_socket_peer_from_mbuf(mbuf,  
 mbuflabel,  
 oldlabel,  
 newlabel); 
struct mbuf *mbuf;
struct label *mbuflabel;
struct label *oldlabel;
struct label *newlabel;
 
参数说明锁定
mbuf从套接字接收到的第一个数据报 
mbuflabelmbuf 的标记  
oldlabel套接字的当前标记 
newlabel将为套接字填写的策略标记 

根据传入的 mbuf 标记,设置某个 stream 套接字的对等标志。 除Unix域的套接字之外,每当一个 stream 套接字接收到第一个数据报时,该函数将被调用。

6.7.3.2.8. mpo_set_socket_peer_from_socket
void fsfuncmpo_set_socket_peer_from_socket(oldsocket,  
 oldsocketlabel,  
 newsocket,  
 newsocketpeerlabel); 
struct socket *oldsocket;
struct label *oldsocketlabel;
struct socket *newsocket;
struct label *newsocketpeerlabel;
 
参数说明锁定
oldsocket本地套接字 
oldsocketlabeloldsocket 的策略标记  
newsocket对等套接字 
newsocketpeerlabel将为newsocket填写的策略标记 

根据传入的远程套接字端点,为一个 stream UNIX 与套接字设置对等标记。 每当相应的套接字对之间进行连接时,该函数将在两端分别被调用。

6.7.3.3. Network Object Labeling Event Operations

6.7.3.3.1. mpo_create_bpfdesc
void fsfuncmpo_create_bpfdesc(cred,  
 bpf_d,  
 bpflabel); 
struct ucred *cred;
struct bpf_d *bpf_d;
struct label *bpflabel;
 
参数说明锁定
cred主体信任状不可改变
bpf_d客体;bpf 描述子 
bpf将为bpf_d填写的策略标记 

根据传入的主体信任状参数,为新建的 BPF 描述子设置标记。 当进程打开 BPF 设备节点时,该函数将被调用。

6.7.3.3.2. mpo_create_ifnet
void fsfuncmpo_create_ifnet(ifnet,  
 ifnetlabel); 
struct ifnet *ifnet;
struct label *ifnetlabel;
 
参数说明锁定
ifnet网络接口 
ifnetlabel将为ifnet填写的策略标记 

为新建的网络接口设置标记。该函数在以下情况下被调用: 当一个新的物理接口变为可用时,或者当一个伪接口在引导时或由于某个用户操作而实例化时。

6.7.3.3.3. mpo_create_ipq
void fsfuncmpo_create_ipq(fragment,  
 fragmentlabel,  
 ipq,  
 ipqlabel); 
struct mbuf *fragment;
struct label *fragmentlabel;
struct ipq *ipq;
struct label *ipqlabel;
 
参数说明锁定
fragment第一个被接收的 IP 分片 
fragmentlabelfragment 的策略标记  
ipq将被标记的 IP 重组队列 
ipqlabel将为ipq填写的策略标记 

根据第一个接收到的分片的 mbuf 头部信息,为新建的 IP 分片重组队列设置标记。

6.7.3.3.4. mpo_create_datagram_from_ipq
void fsfuncmpo_create_create_datagram_from_ipq(ipq,  
 ipqlabel,  
 datagram,  
 datagramlabel); 
struct ipq *ipq;
struct label *ipqlabel;
struct mbuf *datagram;
struct label *datagramlabel;
 
参数说明锁定
ipqIP 重组队列 
ipqlabelipq 的策略标记  
datagram将被标记的数据报 
datagramlabel将为datagramlabel填写的策略标记 

根据 IP 分片重组队列,为刚刚重组完毕的 IP 数据报设置标记。

6.7.3.3.5. mpo_create_fragment
void fsfuncmpo_create_fragment(datagram,  
 datagramlabel,  
 fragment,  
 fragmentlabel); 
struct mbuf *datagram;
struct label *datagramlabel;
struct mbuf *fragment;
struct label *fragmentlabel;
 
参数说明锁定
datagram数据报 
datagramlabeldatagram 的策略标记  
fragment将被标记的分片 
fragmentlabel将为datagram填写的策略标记 

根据数据报所对应的 mbuf 头部信息,为其新建的分片的 mbuf 头部设置标记。

6.7.3.3.6. mpo_create_mbuf_from_mbuf
void fsfuncmpo_create_mbuf_from_mbuf(oldmbuf,  
 oldmbuflabel,  
 newmbuf,  
 newmbuflabel); 
struct mbuf *oldmbuf;
struct label *oldmbuflabel;
struct mbuf *newmbuf;
struct label *newmbuflabel;
 
参数说明锁定
oldmbuf已有的(源)mbuf 
oldmbuflabeloldmbuf 的策略标记  
newmbuf将被标记的新建 mbuf 
newmbuflabel将为newmbuf填写的策略标记 

根据某个现有数据报的 mbuf 头部信息,为新建数据报的 mbuf 头部设置标记。在许多条件下将会调用该函数, 比如,由于对齐要求而重新分配某个 mbuf 时。

6.7.3.3.7. mpo_create_mbuf_linklayer
void fsfuncmpo_create_mbuf_linklayer(ifnet,  
 ifnetlabel,  
 mbuf,  
 mbuflabel); 
struct ifnet *ifnet;
struct label *ifnetlabel;
struct mbuf *mbuf;
struct label *mbuflabel;
 
参数说明锁定
ifnet网络接口 
ifnetlabelifnet 的策略标记  
mbuf新建数据报的 mbuf 头部 
mbuflabel将为mbuf填写的策略标记 

为在给定接口上由于某个链路层响应而新建的数据报的mbuf头部设置标记。 该函数将在若干条件下被调用,比如当IPv4和IPv6协议栈在响应ARP或者ND6时。

6.7.3.3.8. mpo_create_mbuf_from_bpfdesc
void fsfuncmpo_create_mbuf_from_bpfdesc(bpf_d,  
 bpflabel,  
 mbuf,  
 mbuflabel); 
struct bpf_d *bpf_d;
struct label *bpflabel;
struct mbuf *mbuf;
struct label *mbuflabel;
 
参数说明锁定
bpf_dBPF 描述子 
bpflabelbpflabel 的策略标记  
mbuf将被标记的新建 mbuf 
mbuflabel将为mbuf填写的策略标记 

为使用参数 BPF 描述子创建的新数据报的 mbuf 头部设置标记。 当对参数 BPF 描述子所关联的 BPF 设备进行写操作时,该函数将被调用。

6.7.3.3.9. mpo_create_mbuf_from_ifnet
void fsfuncmpo_create_mbuf_from_ifnet(ifnet,  
 ifnetlabel,  
 mbuf,  
 mbuflabel); 
struct ifnet *ifnet;
struct label *ifnetlabel;
struct mbuf *mbuf;
struct label *mbuflabel;
 
参数说明锁定
ifnet网络接口 
ifnetlabelifnetlabel 的策略标记  
mbuf新建数据报的 mbuf 头部 
mbuflabel将为mbuf填写的策略标记 

为从网络接口参数创建的数据报的 mbuf 头部设置标记。

6.7.3.3.10. mpo_create_mbuf_multicast_encap
void fsfuncmpo_create_mbuf_multicast_encap(oldmbuf,  
 oldmbuflabel,  
 ifnet,  
 ifnetlabel,  
 newmbuf,  
 newmbuflabel); 
struct mbuf *oldmbuf;
struct label *oldmbuflabel;
struct ifnet *ifnet;
struct label *ifnetlabel;
struct mbuf *newmbuf;
struct label *newmbuflabel;
 
参数说明锁定
oldmbuf现有数据报的 mbuf 头部 
oldmbuflabeloldmbuf 的策略标记  
ifnet网络接口 
ifnetlabelifnet 的策略标记  
newmbuf将被标记的新建数据报 mbuf 头部 
newmbuflabel将为newmbuf填写的策略标记 

当传入的已有数据报被给定多播封装接口(multicast encapsulation interface)处理时被调用, 为新创建的数据报所在 mbuf 头部设置标记。 每当使用该虚拟接口传递一个mbuf时,将调用该函数。

6.7.3.3.11. mpo_create_mbuf_netlayer
void fsfuncmpo_create_mbuf_netlayer(oldmbuf,  
 oldmbuflabel,  
 newmbuf,  
 newmbuflabel); 
struct mbuf *oldmbuf;
struct label *oldmbuflabel;
struct mbuf *newmbuf;
struct label *newmbuflabel;
 
参数说明锁定
oldmbuf接收的数据报 
oldmbuflabeloldmbuf 的策略标记  
newmbuf新建数据报 
newmbuflabelnewmbuf 的策略标记  

为由 IP 堆栈因为响应接收数据报(oldmbuf)而新建的数据报设置其 mbuf 头部的标记。 许多情况下需要调用该函数,比如,响应 ICMP 请求数据报时。

6.7.3.3.12. mpo_fragment_match
int fsfuncmpo_fragment_match(fragment,  
 fragmentlabel,  
 ipq,  
 ipqlabel); 
struct mbuf *fragment;
struct label *fragmentlabel;
struct ipq *ipq;
struct label *ipqlabel;
 
参数说明锁定
fragmentIP 数据报分片 
fragmentlabelfragment 的策略标记  
ipqIP 分片重组队列 
ipqlabelipq 的策略标记  

根据所传入的 IP 分片重组队列(ipq)的标记, 检查包含一个 IP 数据报(fragment)的 mbuf 的头部是否符合其要求。 符合,则返回1。否则,返回0。 每当 IP 堆栈尝试将一个刚刚接收到的分片放入某个已有的分片重组队列中时,将调用该函数进行安全检查; 如果失败,将为分片重新实例化一个新的分片重组队列。 策略可以利用该入口函数,根据标记或者其他信息阻止不期望的 IP 分片重组。

6.7.3.3.13. mpo_relabel_ifnet
void fsfuncmpo_relabel_ifnet(cred,  
 ifnet,  
 ifnetlabel,  
 newlabel); 
struct ucred *cred;
struct ifnet *ifnet;
struct label *ifnetlabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
ifnet客体;网络接口 
ifnetlabelifnet 的策略标记 
newlabel将为ifnet设置的新标记 

根据所传入的新标记,newlabel,以及主体信任状, cred,对网络接口的标记进行更新。

6.7.3.3.14. mpo_update_ipq
void fsfuncmpo_update_ipq(fragment,  
 fragmentlabel,  
 ipq,  
 ipqlabel); 
struct mbuf *fragment;
struct label *fragmentlabel;
struct ipq *ipq;
struct label *ipqlabel;
 
参数说明锁定
mbufIP 分片 
mbuflabelmbuf 的策略标记  
ipqIP 分片重组队列 
ipqlabel将被更新的ipq的当前策略标记 

根据所传入的 IP 分片 mbuf 头部(mbuf)为接收 它的 IP 分片重组队列(ipq)的标记进行更新。

6.7.3.4. 进程标记事件操作

6.7.3.4.1. mpo_create_cred
void fsfuncmpo_create_cred(parent_cred,  
 child_cred); 
struct ucred *parent_cred;
struct ucred *child_cred;
 
参数说明锁定
parent_cred父主体信任状 
child_cred子主体信任状 

根据所传入的主体信任状,为新建的主体信任状设置标记。 每当为一个新建的 struct ucred调用 crcopy(9) 时,将调用此函数。 该函数不应与进程复制(forking)或者创建事件混为一谈。

6.7.3.4.2. mpo_execve_transition
void fsfuncmpo_execve_transition(old,  
 new,  
 vp,  
 vnodelabel); 
struct ucred *old;
struct ucred *new;
struct vnode *vp;
struct label *vnodelabel;
 
参数说明锁定
old已有的主体信任状不可改变
new将被标记的新主体信任状 
vp将被执行的文件已被锁定
vnodelabelvp 的策略标记  

一个拥有信任状old的主体由于执行(vp文件而导致标记转换时, 该函数根据vnode标记为该主体重新标记为new。 每当一个进程请求执行vnode文件,而通过 入口函数mpo_execve_will_transition 有成功返回的策略时,将调用该函数。 策略模块可以通过传入两个主体信任状和简单地调用 mpo_create_cred 来实现该入口函数, so as not to implement a transitioning event. 一旦策略实现了mpo_create_cred函数,即使没有实现 mpo_execve_will_transition,也应该实现该函数。

6.7.3.4.3. mpo_execve_will_transition
int fsfuncmpo_execve_will_transition(old,  
 vp,  
 vnodelabel); 
struct ucred *old;
struct vnode *vp;
struct label *vnodelabel;
 
参数说明锁定
old在执行execve(2)之前的主体信任状不可改变
vp将被执行的文件 
vnodelabelvp 的策略标记  

由策略决定,当参数主体信任状执行参数 vnode 时,是否需要进行一个标记转换操作。如果需要,返回1; 否则,返回0。即使一个策略返回0,它也必须为自己不期望的对 mpo_execve_transition的调用作好准备,因为只要有其他任何一个策略要求转换,就将执行此函数。

6.7.3.4.4. mpo_create_proc0
void fsfuncmpo_create_proc0(cred); 
struct ucred *cred;
 
参数说明锁定
cred将被填写的主体信任状 

为进程0,所有内核进程的祖先,创建主体信任状。

6.7.3.4.5. mpo_create_proc1
void fsfuncmpo_create_proc1(cred); 
struct ucred *cred;
 
参数说明锁定
cred将被填写的主体信任状 

为进程1,所有用户进程的祖先,创建主体信任状。

6.7.3.4.6. mpo_relabel_cred
void fsfuncmpo_relabel_cred(cred,  
 newlabel); 
struct ucred *cred;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
newlabel将被应用到 cred 上的新标记 

根据传入的新标记,对主体信任状上的标记进行更新。

6.7.4. 访问控制检查

通过访问控制入口函数,策略模块能影响内核的访问控制决策。 通常情况下,不是绝对,一个访问控制入口函数的参数有,一个或者若干个授权信任状,和相关操作涉及的其他任何对象的信息(其中可能包含标记)。 访问控制入口函数返回0,表示允许该操作;否则,返回一个 errno(2) 错误编码。调用该入口函数,将遍历所有系统注册的策略模块,逐一进行 策略相关的检查和决策,之后按照下述方法组合不同策略的返回结果:只有当所有的模块均允许该操作时,才成功返回。 否则,如果有一个或者若干模块失败返回,则整个检查不通过。如果有多个模块的检查出错返回,将由定义在kern_mac.c 中的 error_select() 函数从它们返回的错误编码中,选择一个合适的,返回给用户。

最高优先级EDEADLK
 EINVAL
 ESRCH
 EACCES
最低优先级EPERM

如果所有策略模块返回的错误编码均没有出现在上述优先级序列表中,则任意选择一个返回。 选择错误编码的一般次序为:内核错误,无效的参数,对象不存在,访问被拒绝,和其他错误。

6.7.4.1. mpo_check_bpfdesc_receive

int fsfuncmpo_check_bpfdesc_receive(bpf_d,  
 bpflabel,  
 ifnet,  
 ifnetlabel); 
struct bpf_d *bpf_d;
struct label *bpflabel;
struct ifnet *ifnet;
struct label *ifnetlabel;
 
参数说明锁定
bpf_d主体;BPF 描述子 
bpflabelbpf_d 的策略标记  
ifnet客体;网络接口 
ifnetlabelifnet 的策略标记  

决定 MAC 框架是否应该允许将由参数接口接收到的数据报传递给由 BPF 描述子所对应的缓冲区。成功,则返回0; 否则,返回错误编码信息errno。建议使用的错误编码有:EACCES,用于标记不符的情况; EPERM,用于缺少特权的情况。

6.7.4.2. mpo_check_kenv_dump

int fsfuncmpo_check_kenv_dump(cred); 
struct ucred *cred;
 
参数说明锁定
cred主体信任状 

决定相关主体是否应该被允许查询内核环境状态(参考 kenv(2))。

6.7.4.3. mpo_check_kenv_get

int fsfuncmpo_check_kenv_get(cred,  
 name); 
struct ucred *cred;
char *name;
 
参数说明锁定
cred主体信任状 
name内核的环境变量名字 

决定相关主体是否可以查询内核中给定环境变量的状态。

6.7.4.4. mpo_check_kenv_set

int fsfuncmpo_check_kenv_set(cred,  
 name); 
struct ucred *cred;
char *name;
 
参数说明锁定
cred主体信任状 
name内核的环境变量名字 

决定相关主体是否有权设置给定内核环境变量的值。

6.7.4.5. mpo_check_kenv_unset

int fsfuncmpo_check_kenv_unset(cred,  
 name); 
struct ucred *cred;
char *name;
 
参数说明锁定
cred主体信任状 
name内核的环境变量名字Kernel environment variable name 

决定相关主体是否有权清除给定的内核环境变量的设置。

6.7.4.6. mpo_check_kld_load

int fsfuncmpo_check_kld_load(cred,  
 vp,  
 vlabel); 
struct ucred *cred;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
cred主体信任状 
vp内核模块的 vnode 
vlabelvp的策略标记 

决定相关主体是否有权加载给定的模块文件。

6.7.4.7. mpo_check_kld_stat

int fsfuncmpo_check_kld_stat(cred); 
struct ucred *cred;
 
参数说明锁定
cred主体信任状 

决定相关主体是否有权访问内核的加载模块文件链表以及相关的统计数据。

6.7.4.8. mpo_check_kld_unload

int fsfuncmpo_check_kld_unload(cred); 
struct ucred *cred;
 
参数说明锁定
cred主体信任状 

决定相关主体是否有权卸载一个内核模块。

6.7.4.9. mpo_check_pipe_ioctl

int fsfuncmpo_check_pipe_ioctl(cred,  
 pipe,  
 pipelabel,  
 cmd,  
 data); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
unsigned long cmd;
void *data;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的策略标记 
cmdioctl(2) 命令 
dataioctl(2) 数据 

决定相关主体是否有权调用指定的 ioctl(2) 系统调用。

6.7.4.10. mpo_check_pipe_poll

int fsfuncmpo_check_pipe_poll(cred,  
 pipe,  
 pipelabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的策略标记 

决定相关主体是否有权对管道pipe执行poll操作。

6.7.4.11. mpo_check_pipe_read

int fsfuncmpo_check_pipe_read(cred,  
 pipe,  
 pipelabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的策略标记 

决定该主体是否有权读取pipe

6.7.4.12. mpo_check_pipe_relabel

int fsfuncmpo_check_pipe_relabel(cred,  
 pipe,  
 pipelabel,  
 newlabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的当前策略标记 
newlabel将为pipelabel设置的新标记 

决定该主体是否有权为pipe重新设置标记。

6.7.4.13. mpo_check_pipe_stat

int fsfuncmpo_check_pipe_stat(cred,  
 pipe,  
 pipelabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的策略标记 

决定该主体是否有权查询与pipe相关的统计信息。

6.7.4.14. mpo_check_pipe_write

int fsfuncmpo_check_pipe_write(cred,  
 pipe,  
 pipelabel); 
struct ucred *cred;
struct pipe *pipe;
struct label *pipelabel;
 
参数说明锁定
cred主体信任状 
pipe管道 
pipelabelpipe的策略标记 

决定该主体是否有权写pipe

6.7.4.15. mpo_check_socket_bind

int fsfuncmpo_check_socket_bind(cred,  
 socket,  
 socketlabel,  
 sockaddr); 
struct ucred *cred;
struct socket *socket;
struct label *socketlabel;
struct sockaddr *sockaddr;
 
参数说明锁定
cred主体信任状 
socket将被绑定的套接字 
socketlabelsocket的策略标记 
sockaddrsocket的地址 

6.7.4.16. mpo_check_socket_connect

int fsfuncmpo_check_socket_connect(cred,  
 socket,  
 socketlabel,  
 sockaddr); 
struct ucred *cred;
struct socket *socket;
struct label *socketlabel;
struct sockaddr *sockaddr;
 
参数说明锁定
cred主体信任状 
socket将被连接的套接字 
socketlabelsocket的策略标记 
sockaddrsocket的地址 

决定该主体(cred)是否有权将套接字(socket)绑定到地址 sockaddr。成功,返回0,否则返回一个错误编码errno。 建议采用的错误编码有:EACCES,用于标记不符的情况;EPERM,用于特权不足的情况。

6.7.4.17. mpo_check_socket_receive

int fsfuncmpo_check_socket_receive(cred,  
 so,  
 socketlabel); 
struct ucred *cred;
struct socket *so;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状 
so套接字 
socketlabelso的策略标记 

决定该主体是否有权查询套接字so的相关信息。

6.7.4.18. mpo_check_socket_send

int fsfuncmpo_check_socket_send(cred,  
 so,  
 socketlabel); 
struct ucred *cred;
struct socket *so;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状 
so套接字 
socketlabelso的策略标记 

决定该主体是否有权通过套接字so发送信息。

6.7.4.19. mpo_check_cred_visible

int fsfuncmpo_check_cred_visible(u1,  
 u2); 
struct ucred *u1;
struct ucred *u2;
 
参数说明锁定
u1主体信任状 
u2对象信任状 

确定该主体信任状u1是否有权 see 具有信任状u2 的其他主体。 成功,返回0;否则,返回错误编码errno。建议采用的错误编码有: EACCES,用于标记不符的情况;EPERM,用于特权不足的情况;ESRCH, 用来提供不可见性。该函数可在许多环境下使用,包括命令ps所使用的进程间的状态 sysctl,以及通过procfs 的状态查询操作。

6.7.4.20. mpo_check_socket_visible

int fsfuncmpo_check_socket_visible(cred,  
 socket,  
 socketlabel); 
struct ucred *cred;
struct socket *socket;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状 
socket客体;套接字 
socketlabelsocket的策略标记 

6.7.4.21. mpo_check_ifnet_relabel

int fsfuncmpo_check_ifnet_relabel(cred,  
 ifnet,  
 ifnetlabel,  
 newlabel); 
struct ucred *cred;
struct ifnet *ifnet;
struct label *ifnetlabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
ifnet客体;网络接口 
ifnetlabelifnet现有的策略标记 
newlabel将被应用到ifnet上的新的策略标记 

决定该主体信任状是否有权使用传入的标记更新参数对给定的网络接口的标记进行重新设置。

6.7.4.22. mpo_check_socket_relabel

int fsfuncmpo_check_socket_relabel(cred,  
 socket,  
 socketlabel,  
 newlabel); 
struct ucred *cred;
struct socket *socket;
struct label *socketlabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
socket客体;套接字 
socketlabelsocket现有的策略标记 
newlabel将被应用到socketlabel上的更新标记 

决定该主体信任状是否有权采用传入的标记对套接字参数的标记进行重新设置。

6.7.4.23. mpo_check_cred_relabel

int fsfuncmpo_check_cred_relabel(cred,  
 newlabel); 
struct ucred *cred;
struct label *newlabel;
 
参数说明锁定
cred主体信任状 
newlabel将被应用到cred上的更新标记 

决定该主体信任状是否有权将自己的标记重新设置为给定的更新标记。

6.7.4.24. mpo_check_vnode_relabel

int fsfuncmpo_check_vnode_relabel(cred,  
 vp,  
 vnodelabel,  
 newlabel); 
struct ucred *cred;
struct vnode *vp;
struct label *vnodelabel;
struct label *newlabel;
 
参数说明锁定
cred主体信任状不可改变
vp客体;vnode已被锁定
vnodelabelvp现有的策略标记 
newlabel将被应用到vp上的策略标记 

决定该主体信任状是否有权将参数 vnode 的标记重新设置为指定标记。

6.7.4.25. mpo_check_mount_stat

int fsfuncmpo_check_mount_stat(cred,  
 mp,  
 mountlabel); 
struct ucred *cred;
struct mount *mp;
struct label *mountlabel;
 
参数说明锁定
cred主体信任状 
mp客体;文件系统挂载 
mountlabelmp的策略标记 

确定相关主体信任状是否有权查看在给定文件系统上执行 statfs 的结果。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。 该函数可能在下列情况下被调用: 在 statfs(2) 和其他相关调用期间,或者当需要从文件系统列表中选择排除哪个文件系统时,比如, 调用 getfsstat(2)时。

6.7.4.26. mpo_check_proc_debug

int fsfuncmpo_check_proc_debug(cred,  
 proc); 
struct ucred *cred;
struct proc *proc;
 
参数说明锁定
cred主体信任状不可改变
proc客体;进程 

确定相关主体信任状是否有权 debug 给定进程。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够; ESRCH,用于隐瞒目标的存在。 ptrace(2)ktrace(2) API,以及某些 procfs 操作将调用该函数。

6.7.4.27. mpo_check_vnode_access

int fsfuncmpo_check_vnode_access(cred,  
 vp,  
 label,  
 flags); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int flags;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
flagsaccess(2) 标志 

根据相关主体信任状决定其对给定 vnode 以给定访问标志执行的 access(2) 和其他相关调用的返回值。一般,应采用与mpo_check_vnode_open 相同的语义来实现该函数。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.28. mpo_check_vnode_chdir

int fsfuncmpo_check_vnode_chdir(cred,  
 dvp,  
 dlabel); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
 
参数说明锁定
cred主体信任状 
dvp客体;chdir(2) 的目的 vnode 
dlabeldvp的策略标记 

确定相关主体信任状是否有权将进程工作目录切换到给定 vnode。成功,则返回 0; 否则,返回一个 errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.29. mpo_check_vnode_chroot

int fsfuncmpo_check_vnode_chroot(cred,  
 dvp,  
 dlabel); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
 
参数说明锁定
cred主体信任状 
dvp目录 vnode 
dlabeldvp相关联的策略标记 

确定相关主体是否有权 chroot(2) 到由 (dvp)给定的目录。

6.7.4.30. mpo_check_vnode_create

int fsfuncmpo_check_vnode_create(cred,  
 dvp,  
 dlabel,  
 cnp,  
 vap); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct componentname *cnp;
struct vattr *vap;
 
参数说明锁定
cred主体信任状 
dvp客体;vnode 
dlabeldvp的策略标记 
cnpdvp中的成员名 
vapvap的 vnode 属性 

确定相关主体信任状是否有权在给定父目录,以给定的名字和属性, 常见一个 vnode。成功,则返回 0;否则, 返回一个errno值。 建议使用的错误编码:EACCES 来表示用于标记不匹配, 而用 EPERM,用于权限不足。 以O_CREAT为参数调用 open(2),或对 mknod(2)mkfifo(2) 等的调用将导致该函数被调用。

6.7.4.31. mpo_check_vnode_delete

int fsfuncmpo_check_vnode_delete(cred,  
 dvp,  
 dlabel,  
 vp,  
 label,  
 cnp); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct vnode *vp;
void *label;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
dvp父目录 vnode 
dlabeldvp的策略标记 
vp客体;将被删除的 vnode 
labelvp的策略标记 
cnpvp中的成员名 

确定相关主体信任状是否有权从给定的父目录中,删除给定名字的 vnode。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。 使用 unlink(2)rmdir(2),将导致该函数被调用。 提供该入口函数的策略还必须实现一个 mpo_check_rename_to, 用来授权由于重命名操作导致的目标文件的删除。

6.7.4.32. mpo_check_vnode_deleteacl

int fsfuncmpo_check_vnode_deleteacl(cred,  
 vp,  
 label,  
 type); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
acl_type_t type;
 
参数说明锁定
cred主体信任状不可改变
vp客体;vnode被锁定
labelvp的策略标记 
typeACL 类型 

确定相关主体信任状是否有权删除给定 vnode 的给定类型的 ACL。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.33. mpo_check_vnode_exec

int fsfuncmpo_check_vnode_exec(cred,  
 vp,  
 label); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
 
参数说明锁定
cred主体信任状 
vp客体;将被执行的 vnode  
labelvp的策略标记 

确定相关主体信任状是否有权执行给定 vnode。 对于执行特权的决策与任何瞬时事件的决策是严格分开的。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.34. mpo_check_vnode_getacl

int fsfuncmpo_check_vnode_getacl(cred,  
 vp,  
 label,  
 type); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
acl_type_t type;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
typeACL 类型 

确定相关主体信任状是否有权查询给定 vnode 上的给定类型的 ACL。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.35. mpo_check_vnode_getextattr

int fsfuncmpo_check_vnode_getextattr(cred,  
 vp,  
 label,  
 attrnamespace,  
 name,  
 uio); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int attrnamespace;
const char *name;
struct uio *uio;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
attrnamespace扩展属性名字空间 
name扩展属性名 
uioI/O 结构指针;参见 uio(9) 

确定相关主体信任状是否有权查询给定 vnode 上给定名字空间和名字的扩展属性。 使用扩展属性实现标记存储的策略模块可能会需要对这些扩展属性的操作进行特殊处理。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.36. mpo_check_vnode_link

int fsfuncmpo_check_vnode_link(cred,  
 dvp,  
 dlabel,  
 vp,  
 label,  
 cnp); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct vnode *vp;
struct label *label;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
dvp目录 vnode 
dlabeldvp相关联的策略标记 
vp链接目的 vnode 
labelvp相关联的策略标记 
cnp将被创建的链接对应的成员名 

确定相关主体是否有权为参数vp给定的 vnode 创建一个由参数cnp给定名字的链接。

6.7.4.37. mpo_check_vnode_mmap

int fsfuncmpo_check_vnode_mmap(cred,  
 vp,  
 label,  
 prot); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int prot;
 
参数说明锁定
cred主体信任状 
vp将被映射的 vnode 
labelvp相关联的策略标记 
protmmap 保护 (参见 mmap(2)) 

确定相关主体是否有权将给定 vnode vpprot指定的保护方式进行映射.

6.7.4.38. mpo_check_vnode_mmap_downgrade

void fsfuncmpo_check_vnode_mmap_downgrade(cred,  
 vp,  
 label,  
 prot); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int *prot;
 
参数说明锁定
credSee 第 6.7.4.37 节 “mpo_check_vnode_mmap. 
vp 
label 
prot将被降级的 mmap protections 

根据主体和客体标记,降低 mmap protections。

6.7.4.39. mpo_check_vnode_mprotect

int fsfuncmpo_check_vnode_mprotect(cred,  
 vp,  
 label,  
 prot); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int prot;
 
参数说明锁定
cred主体信任状 
vp映射的 vnode 
prot存储保护 

确定相关主体是否有权将给定 vnodevp 映射内存空间的存储保护参数设置为指定值。

6.7.4.40. mpo_check_vnode_poll

int fsfuncmpo_check_vnode_poll(active_cred,  
 file_cred,  
 vp,  
 label); 
struct ucred *active_cred;
struct ucred *file_cred;
struct vnode *vp;
struct label *label;
 
参数说明锁定
active_cred主体信任状 
file_credstruct file相关联的信任状 
vp将被执行 poll 操作的 vnode 
labelvp相关联的策略标记 

确定相关主体是否有权对给定 vnode vp执行 poll 操作。

6.7.4.41. mpo_check_vnode_rename_from

int fsfuncmpo_vnode_rename_from(cred,  
 dvp,  
 dlabel,  
 vp,  
 label,  
 cnp); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct vnode *vp;
struct label *label;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
dvp目录 vnode 
dlabeldvp相关联的策略标记 
vp将被重命名的 vnode 
labelvp相关联的策略标记 
cnpvp中的成员名 

确定相关主体是否有权重命名给定vnode,vp

6.7.4.42. mpo_check_vnode_rename_to

int fsfuncmpo_check_vnode_rename_to(cred,  
 dvp,  
 dlabel,  
 vp,  
 label,  
 samedir,  
 cnp); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct vnode *vp;
struct label *label;
int samedir;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
dvp目录 vnode 
dlabeldvp相关联的策略标记 
vp被覆盖的 vnode 
labelvp相关联的策略标记 
samedir布尔型变量;如果源和目的目录是相同的,则被置为1 
cnp目标component名 

确定相关主体是否有权重命名给定 vnode vp,至指定目录 dvp,或更名为cnp。如果无需覆盖已有文件, 则vplabel 的值将为 NULL.

6.7.4.43. mpo_check_socket_listen

int fsfuncmpo_check_socket_listen(cred,  
 socket,  
 socketlabel); 
struct ucred *cred;
struct socket *socket;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状 
socket客体;套接字 
socketlabelsocket的策略标记 

确定相关主体是否有权监听给定套接字。 成功,则返回0;否则,返回错误编码值errno。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.44. mpo_check_vnode_lookup

int fsfuncmpo_check_vnode_lookup(,  
 ,  
 ,  
 cnp); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
struct componentname *cnp;
 
参数说明锁定
cred主体信任状 
dvp客体;vnode 
dlabeldvp的策略标记 
cnp被检查的成员名 

确定相关主体信任状是否有权在给定的目录 vnode 中为查找给定名字执行lookup操作。 成功,则返回 0;否则,返回一个 errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.45. mpo_check_vnode_open

int fsfuncmpo_check_vnode_open(cred,  
 vp,  
 label,  
 acc_mode); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int acc_mode;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
acc_modeopen(2) 访问模式 

确定相关主体信任状是否有权在给定 vnode 上以给定的访问模式执行 open 操作。 如果成功,则返回 0;否则,返回一个错误编码。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.46. mpo_check_vnode_readdir

int fsfuncmpo_check_vnode_readdir(,  
 ,  
 ); 
struct ucred *cred;
struct vnode *dvp;
struct label *dlabel;
 
参数说明锁定
cred主体信任状 
dvp客体;目录 vnode 
dlabeldvp的策略标记 

确定相关主体信任状是否有权在给定的目录 vnode 上执行 readdir 操作。 成功,则返回 0;否则,返回一个错误编码 errno。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够。

6.7.4.47. mpo_check_vnode_readlink

int fsfuncmpo_check_vnode_readlink(cred,  
 vp,  
 label); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 

确定相关主体信任状是否有权在给定符号链接 vnode 上执行 readlink 操作。成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够。 该函数可能在若干环境下被调用,包括由用户进程显式执行的 readlink 调用, 或者是在进程执行名字查询时隐式执行的 readlink

6.7.4.48. mpo_check_vnode_revoke

int fsfuncmpo_check_vnode_revoke(cred,  
 vp,  
 label); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 

确定相关主体信任状是否有权撤销对给定 vnode 的访问。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够。

6.7.4.49. mpo_check_vnode_setacl

int fsfuncmpo_check_vnode_setacl(cred,  
 vp,  
 label,  
 type,  
 acl); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
acl_type_t type;
struct acl *acl;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
typeACL 类型 
aclACL 

确定相关主体信任状是否有权设置给定 vnode 的给定类型的 ACL。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够。

6.7.4.50. mpo_check_vnode_setextattr

int fsfuncmpo_check_vnode_setextattr(cred,  
 vp,  
 label,  
 attrnamespace,  
 name,  
 uio); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
int attrnamespace;
const char *name;
struct uio *uio;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
attrnamespace扩展属性名字空间 
name扩展属性名 
uioI/O 结构指针;参见 uio(9) 

确定相关主体信任状是否有权设置给定 vnode 上给定名字空间中给定名字的扩展属性的值。 使用扩展属性备份安全标记的策略模块可能需要对其使用的属性实施额外的保护。另外, 由于在检查和实际操作时间可能存在的竞争, 策略模块应该避免根据来自uio中的数据做出决策。 如果正在执行一个删除操作,则参数 uio 的值也可能为 NULL。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配;EPERM,用于权限不够。

6.7.4.51. mpo_check_vnode_setflags

int fsfuncmpo_check_vnode_setflags(cred,  
 vp,  
 label,  
 flags); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
u_long flags;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
flags文件标志;参见 chflags(2) 

确定相关主体信任状是否有权为给定的 vnode 设置给定的标志。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.52. mpo_check_vnode_setmode

int fsfuncmpo_check_vnode_setmode(cred,  
 vp,  
 label,  
 mode); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
mode_t mode;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
mode文件模式;参见 chmod(2) 

确定相关主体信任状是否有权将给定 vnode 的模式设置为给定值。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.53. mpo_check_vnode_setowner

int fsfuncmpo_check_vnode_setowner(cred,  
 vp,  
 label,  
 uid,  
 gid); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
uid_t uid;
gid_t gid;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 
uid用户ID 
gid组ID 

确定相关主体信任状是否有权将给定 vnode 的文件 uid 和文件 gid 设置为给定值。如果无需更新, 相关参数值可能被设置为(-1)。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.54. mpo_check_vnode_setutimes

int fsfuncmpo_check_vnode_setutimes(,  
 ,  
 ,  
 ,  
 ); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
struct timespec atime;
struct timespec mtime;
 
参数说明锁定
cred主体信任状 
vp客体;vp 
labelvp的策略标记 
atime访问时间;参见 utimes(2) 
mtime修改时间;参见 utimes(2) 

确定相关主体信任状是否有权将给定 vnode 的访问时间标签设置为给定值。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.55. mpo_check_proc_sched

int fsfuncmpo_check_proc_sched(ucred,  
 proc); 
struct ucred *ucred;
struct proc *proc;
 
参数说明锁定
cred主体信任状 
proc客体;进程 

确定相关主体信任状是否有权改变给定进程的调度参数。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够; ESRCH,用于提供不可见性质。

See setpriority(2) for more information.

6.7.4.56. mpo_check_proc_signal

int fsfuncmpo_check_proc_signal(cred,  
 proc,  
 signal); 
struct ucred *cred;
struct proc *proc;
int signal;
 
参数说明锁定
cred主体信任状 
proc客体;进程 
signal信号;参见 kill(2) 

确定相关主体信任状是否有权向给定进程发送给定信号。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES, 用于标记不匹配;EPERM,用于权限不够; ESRCH,用于提供不可见性质。

6.7.4.57. mpo_check_vnode_stat

int fsfuncmpo_check_vnode_stat(cred,  
 vp,  
 label); 
struct ucred *cred;
struct vnode *vp;
struct label *label;
 
参数说明锁定
cred主体信任状 
vp客体;vnode 
labelvp的策略标记 

确定相关主体信任状是否有权在给定 vnode 上执行 stat 操作。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

See stat(2) for more information.

6.7.4.58. mpo_check_ifnet_transmit

int fsfuncmpo_check_ifnet_transmit(cred,  
 ifnet,  
 ifnetlabel,  
 mbuf,  
 mbuflabel); 
struct ucred *cred;
struct ifnet *ifnet;
struct label *ifnetlabel;
struct mbuf *mbuf;
struct label *mbuflabel;
 
参数说明锁定
cred主体信任状 
ifnet网络接口 
ifnetlabelifnet的策略标记 
mbuf客体;将被发送的 mbuf  
mbuflabelmbuf的策略标记 

确定相关网络接口是否有权传送给定的 mbuf。成功,则返回 0; 否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.59. mpo_check_socket_deliver

int fsfuncmpo_check_socket_deliver(cred,  
 ifnet,  
 ifnetlabel,  
 mbuf,  
 mbuflabel); 
struct ucred *cred;
struct ifnet *ifnet;
struct label *ifnetlabel;
struct mbuf *mbuf;
struct label *mbuflabel;
 
参数说明锁定
cred主体信任状 
ifnet网络接口 
ifnetlabelifnet的策略标记 
mbuf客体;将被传送的 mbuf  
mbuflabelmbuf的策略标记 

确定相关套接字是否有权从给定的 mbuf 中接收数据报。 成功,则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够。

6.7.4.60. mpo_check_socket_visible

int fsfuncmpo_check_socket_visible(cred,  
 so,  
 socketlabel); 
struct ucred *cred;
struct socket *so;
struct label *socketlabel;
 
参数说明锁定
cred主体信任状不可改变
so客体;套接字 
socketlabelso的策略标记 

确定相关主体信任状cred 是否有权使用系统监控函数,比如, 由netstat(8)sockstat(1)使用的程序来观察 给定的套接字(socket)。成功, 则返回 0;否则,返回一个errno值。 建议使用的错误编码:EACCES,用于标记不匹配; EPERM,用于权限不够; ESRCH,用于提供不可见性质。

6.7.4.61. mpo_check_system_acct

int fsfuncmpo_check_system_acct(ucred,  
 vp,  
 vlabel); 
struct ucred *ucred;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
ucred主体信任状 
vp审计文件;acct(5) 
vlabelvp相关联的标记 

根据主体标记和审计日志文件的标记,确定该主体是否有权启动审计。

6.7.4.62. mpo_check_system_nfsd

int fsfuncmpo_check_system_nfsd(cred); 
struct ucred *cred;
 
参数说明锁定
cred主体信任状 

确定相关主体是否有权调用 nfssvc(2)

6.7.4.63. mpo_check_system_reboot

int fsfuncmpo_check_system_reboot(cred,  
 howto); 
struct ucred *cred;
int howto;
 
参数说明锁定
cred主体信任状 
howto来自 reboot(2)howto 参数 

确定相关主体是否有权以指定方式重启系统。

6.7.4.64. mpo_check_system_settime

int fsfuncmpo_check_system_settime(cred); 
struct ucred *cred;
 
参数说明锁定
cred主体信任状 

确定相关用户是否有权设置系统时钟。

6.7.4.65. mpo_check_system_swapon

int fsfuncmpo_check_system_swapon(cred,  
 vp,  
 vlabel); 
struct ucred *cred;
struct vnode *vp;
struct label *vlabel;
 
参数说明锁定
cred主体信任状 
vpswap设备 
vlabelvp相关联的标记 

确定相关主体是否有权增加一个作为swap设备的 vp

6.7.4.66. mpo_check_system_sysctl

int fsfuncmpo_check_system_sysctl(cred,  
 name,  
 namelen,  
 old,  
 oldlenp,  
 inkernel,  
 new,  
 newlen); 
struct ucred *cred;
int *name;
u_int *namelen;
void *old;
size_t *oldlenp;
int inkernel;
void *new;
size_t newlen;
 
参数说明锁定
cred主体信任状 
name参见 sysctl(3) 
namelen 
old 
oldlenp 
inkernel布尔型变量;如果从内核被调用,其值被置为1 
new参见 sysctl(3) 
newlen 

确定相关主体是否应该被允许执行指定的 sysctl(3) 事务。

6.7.5. 标记管理调用

当用户进程请求对某个对象的标记进行修改时,将引发重新标记事件。对应的更新操作分两步进行: 首先,进行访问控制检查,确认此次更新操作是有效且被允许的;然后,调用另一个独立的入口函数对标记进行修改。 重新标记入口函数通常接收由请求进程提交的对象、对象标记指针和请求新标记,作为输入参数。 对象重新标记操作的失败将由先期的标记检查报告,所以,不允许在接下来的标记修改过程中报告失败,故而不提倡在此过程中新分配内存。

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.