6.7.2.1. mpo_init_bpfdesc_label
void
fsfuncmpo_init_bpfdesc_label( | label) ; | |
struct label
*label
;
为一个新近实例化的 bpfdesc(BPF 描述子)初始化标记。可以睡眠。
6.7.2.2. mpo_init_cred_label
void
fsfuncmpo_init_cred_label( | label) ; | |
struct label
*label
;
为一个新近实例化的用户信任状初始化标记。可以睡眠。
6.7.2.3. mpo_init_devfsdirent_label
void
fsfuncmpo_init_devfsdirent_label( | label) ; | |
struct label
*label
;
为一个新近实例化的 devfs 表项初始化标记。可以睡眠。
6.7.2.4. mpo_init_ifnet_label
void
fsfuncmpo_init_ifnet_label( | label) ; | |
struct label
*label
;
为一个新近实例化的网络接口初始化标记。可以睡眠。
6.7.2.5. mpo_init_ipq_label
void
fsfuncmpo_init_ipq_label( | label, | |
| flag) ; | |
struct label
*label
;
int flag
;
为一个新近实例化的 IP 分片重组队列初始化标记。其中的flag
域可能取M_WAITOK
或M_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
;
为一个新近实例化的 mbuf 数据包头部(mbuf
)初始化标记。
其中的flag
的值可能取M_WAITOK和M_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
;
为一个新近实例化的 mount 点初始化标记。可以睡眠。
6.7.2.8. mpo_init_mount_fs_label
void
fsfuncmpo_init_mount_fs_label( | label) ; | |
struct label
*label
;
为一个新近加载的文件系统初始化标记。可以睡眠。
6.7.2.9. mpo_init_pipe_label
void
fsfuncmpo_init_pipe_label( | label) ; | |
struct
label*label
;
为一个刚刚实例化的管道初始化安全标记。可以睡眠。
6.7.2.10. mpo_init_socket_label
void
fsfuncmpo_init_socket_label( | label, | |
| flag) ; | |
struct label
*label
;
int flag
;
为一个刚刚实例化的套接字初始化安全标记。其中的 flag
域的值必须被指定为
M_WAITOK和M_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
;
为刚刚实例化的套接字对等体进行标记的初始化。其中的 flag
域的值必须被指定为
M_WAITOK 和 M_NOWAIT 之一,以避免在该初始化程中使用可能睡眠的
malloc(9)。
6.7.2.12. mpo_init_proc_label
void
fsfuncmpo_init_proc_label( | label) ; | |
struct label
*label
;
为一个刚刚实例化的进程初始化安全标记。可以睡眠。
6.7.2.13. mpo_init_vnode_label
void
fsfuncmpo_init_vnode_label( | label) ; | |
struct label
*label
;
为一个刚刚实例化的 vnode 初始化安全标记。可以睡眠。
6.7.2.14. mpo_destroy_bpfdesc_label
void
fsfuncmpo_destroy_bpfdesc_label( | label) ; | |
struct label
*label
;
销毁一个 BPF 描述子上的标记。在该入口函数中,策略应当释放所有在内部分配与 label
相关联的存储空间,以便销毁该标记。
6.7.2.15. mpo_destroy_cred_label
void
fsfuncmpo_destroy_cred_label( | label) ; | |
struct label
*label
;
销毁一个信任状上的标记。在该入口函数中,策略应当释放所有在内部分配的与 label
相关联的存储空间,以便销毁该标记。
6.7.2.16. mpo_destroy_devfsdirent_label
void
fsfuncmpo_destroy_devfsdirent_label( | label) ; | |
struct label
*label
;
销毁一个 devfs 表项上的标记。在该入口函数中,策略应当释放所有在内部分配的与 label
相关联的存储空间,以便销毁该标记。
6.7.2.17. mpo_destroy_ifnet_label
void
fsfuncmpo_destroy_ifnet_label( | label) ; | |
struct label
*label
;
销毁与一个已删除接口相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label
相关联的存储空间,以便销毁该标记。
6.7.2.18. mpo_destroy_ipq_label
void
fsfuncmpo_destroy_ipq_label( | label) ; | |
struct label
*label
;
销毁与一个 IP 分片队列相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label
相关联的存储空间,以便销毁该标记。
6.7.2.19. mpo_destroy_mbuf_label
void
fsfuncmpo_destroy_mbuf_label( | label) ; | |
struct label
*label
;
销毁与一个 Mbuf 相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 label
相关联的存储空间,以便销毁该标记。
6.7.2.20. mpo_destroy_mount_label
void
fsfuncmpo_destroy_mount_label( | label) ; | |
struct label
*label
;
销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的与 mntlabel
相关联的存储空间,以便销毁该标记。
6.7.2.21. mpo_destroy_mount_label
void
fsfuncmpo_destroy_mount_label( | mntlabel, | |
| fslabel) ; | |
struct label
*mntlabel
;
struct label
*fslabel
;
销毁与一个 mount 点相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 mntlabel
和fslabel
相关联的存储空间,以便销毁该标记。
6.7.2.22. mpo_destroy_socket_label
void
fsfuncmpo_destroy_socket_label( | label) ; | |
struct label
*label
;
销毁与一个套接字相关联的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label
相关联的存储空间,以便销毁该标记。
6.7.2.23. mpo_destroy_socket_peer_label
void
fsfuncmpo_destroy_socket_peer_label( | peerlabel) ; | |
struct label
*peerlabel
;
销毁与一个套接字相关联的对等实体标记。在该入口函数中,策略应当释放所有在内部分配的,与 label
相关联的存储空间,以便销毁该标记。
6.7.2.24. mpo_destroy_pipe_label
void
fsfuncmpo_destroy_pipe_label( | label) ; | |
struct label
*label
;
销毁一个管道的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label
相关联的存储空间,以便销毁该标记。
6.7.2.25. mpo_destroy_proc_label
void
fsfuncmpo_destroy_proc_label( | label) ; | |
struct label
*label
;
销毁一个进程的标记。在该入口函数中,策略应当释放所有在内部分配的,与 label
相关联的存储空间,以便销毁该标记。
6.7.2.26. mpo_destroy_vnode_label
void
fsfuncmpo_destroy_vnode_label( | label) ; | |
struct 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
中。
6.7.2.28. mpo_copy_pipe_label
void
fsfuncmpo_copy_pipe_label( | src, | |
| dest) ; | |
struct label
*src
;
struct label
*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
。
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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据传入的标记结构,产生一个以外部形式表示的标记。
一个外部形式标记,是标记内容的文本表示,它由用户级的应用程序使用,是用户可读的。
目前的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
;
根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。
目前的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
;
根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。
目前的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
;
根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。
目前的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
;
根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。
目前的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
;
根据一个文本形式的外部表示标记数据,创建一个内部形式的标记结构。
目前的MAC方案将依次调用所有策略的相关入口函数,来响应标记的内部转换请求,
因此,实现代码必须首先通过比较element_name中的内容和自己的策略名字,
来确定是否需要转换element_data中存放的数据。
类似的,如果名字不匹配或者数据转换操作成功,该函数返回0,并递增*claimed的值。
策略模块使用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.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
;
根据参数 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
;
从文件系统扩展属性中读取 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
;
在非多重标记文件系统上,使用该入口函数,根据文件系统标记,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
;
为传入设备新建的 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
;
为传入目录参数的新建 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
;
为新近创建的 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
;
将 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
;
为传入的主体信任状所创建的挂载点填写标记。该函数将在文件系统挂载时被调用。
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
;
根据传入的新标记和主体信任状,更新参数 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
;
将参数 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 vnode 标记,对 devfs_dirent
的标记进行更新。
重新标记一个 devfs vnode 的操作成功之后,将调用该函数来确认标记的改变,如此,即使相应的 vnode 数据结构被内核回收重用,
也不会丢失标记的新状态。另外,在 devfs 中新建一个符号链接时,紧接着mac_vnode_create_from_vnode
,
也将调用该函数,对 vnode 标记进行初始化操作。
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
;
根据传入的套接字标记为新创建的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
;
根据传入的主体信任状参数,设置新建管道的标记。每当一个新管道被创建,该函数将被调用。
6.7.3.2.3. mpo_create_socket
void
fsfuncmpo_create_socket( | cred, | |
| so, | |
| socketlabel) ; | |
struct ucred
*cred
;
struct socket
*so
;
struct label
*socketlabel
;
根据传入的主体信任状参数,设置新建套接字的标记。每当新建一个套接字,该函数将被调用。
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
;
根据 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
;
为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
;
根据传入的标记参数,对套接字的当前标记进行更新。
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 标记,设置某个 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
;
根据传入的远程套接字端点,为一个 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
;
根据传入的主体信任状参数,为新建的 BPF 描述子设置标记。
当进程打开 BPF 设备节点时,该函数将被调用。
6.7.3.3.2. mpo_create_ifnet
void
fsfuncmpo_create_ifnet( | ifnet, | |
| ifnetlabel) ; | |
struct ifnet
*ifnet
;
struct label
*ifnetlabel
;
为新建的网络接口设置标记。该函数在以下情况下被调用:
当一个新的物理接口变为可用时,或者当一个伪接口在引导时或由于某个用户操作而实例化时。
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
;
根据第一个接收到的分片的 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
;
根据 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
;
根据数据报所对应的 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
;
根据某个现有数据报的 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
;
为在给定接口上由于某个链路层响应而新建的数据报的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 描述子创建的新数据报的 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
;
为从网络接口参数创建的数据报的 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
;
当传入的已有数据报被给定多播封装接口(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
;
为由 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
;
根据所传入的 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
;
根据所传入的新标记,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
;
根据所传入的 IP 分片 mbuf 头部(mbuf
)为接收
它的 IP 分片重组队列(ipq
)的标记进行更新。
6.7.3.4.1. mpo_create_cred
void
fsfuncmpo_create_cred( | parent_cred, | |
| child_cred) ; | |
struct ucred
*parent_cred
;
struct ucred
*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
的主体由于执行(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
;
由策略决定,当参数主体信任状执行参数 vnode 时,是否需要进行一个标记转换操作。如果需要,返回1;
否则,返回0。即使一个策略返回0,它也必须为自己不期望的对
mpo_execve_transition
的调用作好准备,因为只要有其他任何一个策略要求转换,就将执行此函数。
6.7.3.4.4. mpo_create_proc0
void
fsfuncmpo_create_proc0( | cred) ; | |
struct ucred
*cred
;
为进程0,所有内核进程的祖先,创建主体信任状。
6.7.3.4.5. mpo_create_proc1
void
fsfuncmpo_create_proc1( | cred) ; | |
struct ucred
*cred
;
为进程1,所有用户进程的祖先,创建主体信任状。
6.7.3.4.6. mpo_relabel_cred
void
fsfuncmpo_relabel_cred( | cred, | |
| newlabel) ; | |
struct ucred
*cred
;
struct label
*newlabel
;
根据传入的新标记,对主体信任状上的标记进行更新。
通过访问控制入口函数,策略模块能影响内核的访问控制决策。
通常情况下,不是绝对,一个访问控制入口函数的参数有,一个或者若干个授权信任状,和相关操作涉及的其他任何对象的信息(其中可能包含标记)。
访问控制入口函数返回0,表示允许该操作;否则,返回一个 errno(2) 错误编码。调用该入口函数,将遍历所有系统注册的策略模块,逐一进行
策略相关的检查和决策,之后按照下述方法组合不同策略的返回结果:只有当所有的模块均允许该操作时,才成功返回。
否则,如果有一个或者若干模块失败返回,则整个检查不通过。如果有多个模块的检查出错返回,将由定义在kern_mac.c
中的
error_select()
函数从它们返回的错误编码中,选择一个合适的,返回给用户。
如果所有策略模块返回的错误编码均没有出现在上述优先级序列表中,则任意选择一个返回。
选择错误编码的一般次序为:内核错误,无效的参数,对象不存在,访问被拒绝,和其他错误。
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
;
决定 MAC 框架是否应该允许将由参数接口接收到的数据报传递给由 BPF 描述子所对应的缓冲区。成功,则返回0;
否则,返回错误编码信息errno
。建议使用的错误编码有:EACCES,用于标记不符的情况;
EPERM,用于缺少特权的情况。
6.7.4.2. mpo_check_kenv_dump
int
fsfuncmpo_check_kenv_dump( | cred) ; | |
struct ucred
*cred
;
决定相关主体是否应该被允许查询内核环境状态(参考 kenv(2))。
6.7.4.3. mpo_check_kenv_get
int
fsfuncmpo_check_kenv_get( | cred, | |
| name) ; | |
struct ucred
*cred
;
char *name
;
决定相关主体是否可以查询内核中给定环境变量的状态。
6.7.4.4. mpo_check_kenv_set
int
fsfuncmpo_check_kenv_set( | cred, | |
| name) ; | |
struct ucred
*cred
;
char *name
;
决定相关主体是否有权设置给定内核环境变量的值。
6.7.4.5. mpo_check_kenv_unset
int
fsfuncmpo_check_kenv_unset( | cred, | |
| name) ; | |
struct ucred
*cred
;
char *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
;
决定相关主体是否有权加载给定的模块文件。
6.7.4.7. mpo_check_kld_stat
int
fsfuncmpo_check_kld_stat( | cred) ; | |
struct ucred
*cred
;
决定相关主体是否有权访问内核的加载模块文件链表以及相关的统计数据。
6.7.4.8. mpo_check_kld_unload
int
fsfuncmpo_check_kld_unload( | cred) ; | |
struct ucred
*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
;
决定相关主体是否有权调用指定的 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
;
决定相关主体是否有权对管道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
;
决定该主体是否有权读取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
;
决定该主体是否有权为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
;
决定该主体是否有权查询与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
;
决定该主体是否有权写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
;
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
)绑定到地址
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
;
决定该主体是否有权查询套接字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
;
决定该主体是否有权通过套接字so
发送信息。
6.7.4.19. mpo_check_cred_visible
int
fsfuncmpo_check_cred_visible( | u1, | |
| u2) ; | |
struct ucred
*u1
;
struct ucred
*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
;
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
;
决定该主体信任状是否有权使用传入的标记更新参数对给定的网络接口的标记进行重新设置。
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
;
决定该主体信任状是否有权采用传入的标记对套接字参数的标记进行重新设置。
6.7.4.23. mpo_check_cred_relabel
int
fsfuncmpo_check_cred_relabel( | cred, | |
| newlabel) ; | |
struct ucred
*cred
;
struct label
*newlabel
;
决定该主体信任状是否有权将自己的标记重新设置为给定的更新标记。
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
;
决定该主体信任状是否有权将参数 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
;
确定相关主体信任状是否有权查看在给定文件系统上执行 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
;
确定相关主体信任状是否有权 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
;
根据相关主体信任状决定其对给定 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
;
确定相关主体信任状是否有权将进程工作目录切换到给定 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
;
确定相关主体是否有权 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
;
确定相关主体信任状是否有权在给定父目录,以给定的名字和属性,
常见一个 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
;
确定相关主体信任状是否有权从给定的父目录中,删除给定名字的 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
;
确定相关主体信任状是否有权删除给定 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
;
确定相关主体信任状是否有权执行给定 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
;
确定相关主体信任状是否有权查询给定 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
;
确定相关主体信任状是否有权查询给定 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
;
确定相关主体是否有权为参数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
;
确定相关主体是否有权将给定 vnode vp
以
prot
指定的保护方式进行映射.
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
;
根据主体和客体标记,降低 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
;
确定相关主体是否有权将给定 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
;
确定相关主体是否有权对给定 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
;
确定相关主体是否有权重命名给定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
;
确定相关主体是否有权重命名给定 vnode vp
,至指定目录
dvp
,或更名为cnp
。如果无需覆盖已有文件,
则vp
和
label
的值将为 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
;
确定相关主体是否有权监听给定套接字。
成功,则返回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
;
确定相关主体信任状是否有权在给定的目录 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
;
确定相关主体信任状是否有权在给定 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
;
确定相关主体信任状是否有权在给定的目录 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
;
确定相关主体信任状是否有权在给定符号链接 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
;
确定相关主体信任状是否有权撤销对给定 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
;
确定相关主体信任状是否有权设置给定 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
;
确定相关主体信任状是否有权设置给定 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
;
确定相关主体信任状是否有权为给定的 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
;
确定相关主体信任状是否有权将给定 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
;
确定相关主体信任状是否有权将给定 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
;
确定相关主体信任状是否有权将给定 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
;
确定相关主体信任状是否有权改变给定进程的调度参数。
成功,则返回 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
;
确定相关主体信任状是否有权向给定进程发送给定信号。
成功,则返回 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
;
确定相关主体信任状是否有权在给定 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
;
确定相关网络接口是否有权传送给定的 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
;
确定相关套接字是否有权从给定的 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 是否有权使用系统监控函数,比如,
由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
;
根据主体标记和审计日志文件的标记,确定该主体是否有权启动审计。
6.7.4.62. mpo_check_system_nfsd
int
fsfuncmpo_check_system_nfsd( | cred) ; | |
struct ucred
*cred
;
确定相关主体是否有权调用
nfssvc(2)。
6.7.4.63. mpo_check_system_reboot
int
fsfuncmpo_check_system_reboot( | cred, | |
| howto) ; | |
struct ucred
*cred
;
int howto
;
确定相关主体是否有权以指定方式重启系统。
6.7.4.64. mpo_check_system_settime
int
fsfuncmpo_check_system_settime( | cred) ; | |
struct ucred
*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
;
确定相关主体是否有权增加一个作为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
;
确定相关主体是否应该被允许执行指定的 sysctl(3) 事务。