Linux 安全模块开发

基于 https://lore.kernel.org/r/20071026073721.618b4778@laptopd505.fenrus.org,当 LSM 的意图(描述它试图防御的内容以及在何种情况下期望使用它)已在 Documentation/admin-guide/LSM/ 中得到适当记录时,新的 LSM 将被内核接受。这使得 LSM 的代码可以轻松地与其目标进行比较,以便最终用户和发行版可以就哪些 LSM 适合他们的需求做出更明智的决定。

有关可用 LSM 钩子接口的详细文档,请参阅 security/security.c 和相关结构

void security_free_mnt_opts(void **mnt_opts)

释放与挂载选项关联的内存

参数

void **mnt_opts

LSM 处理的挂载选项

描述

释放与 mnt_ops 关联的内存。

int security_sb_eat_lsm_opts(char *options, void **mnt_opts)

使用 LSM 挂载选项

参数

char *options

挂载选项

void **mnt_opts

LSM 处理的挂载选项

描述

使用(扫描 options)并将它们保存在 mnt_opts 中。

返回

成功时返回 0,失败时返回负值。

int security_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)

检查是否允许新的挂载选项

参数

struct super_block *sb

文件系统超级块

void *mnt_opts

新的挂载选项

描述

确定是否允许 mnt_opts 中的新挂载选项,给定 sb 上现有的挂载文件系统。正在比较的 sb 超级块。

返回

如果选项兼容,则返回 0。

int security_sb_remount(struct super_block *sb, void *mnt_opts)

验证重新挂载期间没有不兼容的挂载更改

参数

struct super_block *sb

文件系统超级块

void *mnt_opts

(重新)挂载选项

描述

提取安全系统特定的挂载选项,并验证是否正在对这些选项进行任何更改。

返回

如果授予权限,则返回 0。

int security_sb_set_mnt_opts(struct super_block *sb, void *mnt_opts, unsigned long kern_flags, unsigned long *set_kern_flags)

设置文件系统的挂载选项

参数

struct super_block *sb

文件系统超级块

void *mnt_opts

二进制挂载选项

unsigned long kern_flags

内核标志(输入)

unsigned long *set_kern_flags

内核标志(输出)

描述

设置用于超级块的安全相关挂载选项。

返回

成功时返回 0,失败时返回错误。

int security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb, unsigned long kern_flags, unsigned long *set_kern_flags)

复制超级块挂载选项

参数

const struct super_block *oldsb

源超级块

struct super_block *newsb

目标超级块

unsigned long kern_flags

内核标志(输入)

unsigned long *set_kern_flags

内核标志(输出)

描述

将所有安全选项从给定的超级块复制到另一个超级块。

返回

成功时返回 0,失败时返回错误。

int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, struct lsm_context *lsmctx)

执行 dentry 初始化

参数

struct dentry *dentry

要初始化的 dentry

int mode

用于确定资源类型的模式

const struct qstr *name

最后一个路径组件的名称

const char **xattr_name

security/LSM xattr 的名称

struct lsm_context *lsmctx

指向结果 LSM 上下文的指针

描述

为 dentry 计算上下文,因为 inode 尚不可用,因为 NFSv4 无论如何都没有由 EA 支持的标签。需要注意的是,xattr_name 不需要由调用者释放,它是一个静态字符串。

返回

成功时返回 0,失败时返回负值。

int security_dentry_create_files_as(struct dentry *dentry, int mode, struct qstr *name, const struct cred *old, struct cred *new)

执行 dentry 初始化

参数

struct dentry *dentry

要初始化的 dentry

int mode

用于确定资源类型的模式

struct qstr *name

最后一个路径组件的名称

const struct cred *old

用于 LSM 上下文计算的凭据

struct cred *new

要修改的凭据

描述

为 dentry 计算上下文,因为 inode 尚不可用,并在传入的凭据中设置该上下文,以便使用该上下文创建新文件。上下文是使用传入的凭据而不是调用者的凭据计算的。

返回

成功时返回 0,失败时返回错误。

int security_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const initxattrs initxattrs, void *fs_data)

初始化 inode 的 LSM 上下文

参数

struct inode *inode

inode

struct inode *dir

父目录

const struct qstr *qstr

路径名的最后一个组件

const initxattrs initxattrs

用于写入 xattr 的回调函数

void *fs_data

文件系统特定数据

描述

获取要设置在新创建的 inode 上的安全属性名称后缀和值,并为新 inode 设置 incore 安全字段。此挂钩由 fs 代码作为 inode 创建事务的一部分调用,并提供 inode 的原子标记,这与 VFS 调用的 post_create/mkdir/... 挂钩不同。

预计挂钩函数会填充 xattrs 数组,方法是调用 lsm_get_xattr_slot() 来检索安全模块使用 lsm_blob_sizes 结构的 lbs_xattr_count 字段保留的槽。对于每个槽,挂钩函数应将 ->name 设置为属性名称后缀(例如 selinux),分配 ->value(将由调用者释放)并将其设置为属性值,将 ->value_len 设置为值的长度。如果安全模块不使用安全属性,或者不希望在此特定 inode 上放置安全属性,则应返回 -EOPNOTSUPP 以跳过此处理。

返回

如果 LSM 成功初始化所有必需的 inode,则返回 0

否则返回负值。

int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev)

检查是否允许创建特殊文件

参数

const struct path *dir

父目录

struct dentry *dentry

新文件

umode_t mode

新文件模式

unsigned int dev

设备号

描述

检查创建文件时的权限。请注意,即使对于常规文件执行 mknod 操作,也会调用此挂钩。

返回

如果授予权限,则返回 0。

int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t mode)

检查是否允许创建新目录

参数

const struct path *dir

父目录

struct dentry *dentry

新目录

umode_t mode

新目录模式

描述

检查在现有目录中创建新目录的权限。

返回

如果授予权限,则返回 0。

检查是否允许删除硬链接

参数

const struct path *dir

父目录

struct dentry *dentry

文件

描述

检查删除文件的硬链接的权限。

返回

如果授予权限,则返回 0。

int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry, unsigned int flags)

检查是否允许重命名文件

参数

const struct path *old_dir

旧文件的父目录

struct dentry *old_dentry

旧文件

const struct path *new_dir

新文件的父目录

struct dentry *new_dentry

新文件

unsigned int flags

标志

描述

检查重命名文件或目录的权限。

返回

如果授予权限,则返回 0。

int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)

检查是否允许创建文件

参数

struct inode *dir

父目录

struct dentry *dentry

正在创建的文件

umode_t mode

请求的文件模式

描述

检查创建常规文件的权限。

返回

如果授予权限,则返回 0。

int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)

检查是否允许创建新目录

参数

struct inode *dir

父目录

struct dentry *dentry

新目录

umode_t mode

新目录模式

描述

检查在与 inode 结构 dir 关联的现有目录中创建新目录的权限。

返回

如果授予权限,则返回 0。

int security_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)

检查是否允许设置文件属性

参数

struct mnt_idmap *idmap

挂载的 idmap

struct dentry *dentry

文件

struct iattr *attr

新属性

描述

在设置文件属性之前检查权限。请注意,每当文件属性发生更改时(例如,当文件被截断、chown/chmod 操作、传输磁盘配额等时),都会从多个位置执行内核对 notify_change 的调用。

返回

如果授予权限,则返回 0。

int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)

列出 xattr 安全标签名称

参数

struct inode *inode

inode

char *buffer

缓冲区

size_t buffer_size

缓冲区大小

描述

将与 inode 关联的安全标签的扩展属性名称复制到 buffer 中。buffer 的最大大小由 buffer_size 指定。buffer 可以为 NULL 以请求所需缓冲区的大小。

返回

成功时返回已使用/所需的字节数。

int security_inode_copy_up(struct dentry *src, struct cred **new)

为 overlayfs 复制操作创建新凭据

参数

struct dentry *src

复制文件的联合 dentry

struct cred **new

新创建的凭据

描述

文件即将从 overlay 文件系统的较低层复制到较高层。安全模块可以准备一组新凭据并根据需要进行修改,然后返回新凭据。调用者将临时切换到新凭据以创建新文件并释放新分配的凭据。

返回

成功时返回 0,出错时返回负错误代码。

int security_inode_copy_up_xattr(struct dentry *src, const char name)

过滤 overlayfs 复制操作中的 xattr

参数

struct dentry *src

复制文件的联合 dentry

const char *name

xattr 名称

描述

当联合文件从较低层复制到联合/覆盖层时,过滤要复制的 xattr。调用者负责读取和写入 xattr,此挂钩仅是一个过滤器。

返回

返回 0 以接受 xattr,返回 -ECANCELED 以放弃 xattr,

如果安全模块不知道该属性,则返回 -EOPNOTSUPP,如果中止复制,则返回负错误代码。

int security_inode_setintegrity(const struct inode *inode, enum lsm_integrity_type type, const void *value, size_t size)

设置 inode 的完整性数据

参数

const struct inode *inode

inode

enum lsm_integrity_type type

完整性的类型,例如哈希摘要、签名等

const void *value

完整性值

size_t size

完整性值的大小

描述

向 LSM 注册 inode 的已验证完整性度量。如果 value 为 NULL,LSM 应该释放先前保存的数据。

返回

成功时返回 0,失败时返回负值。

int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

检查是否允许 ioctl

参数

struct file *file

关联文件

unsigned int cmd

ioctl 命令

unsigned long arg

ioctl 参数

描述

检查对 file 执行 ioctl 操作的权限。请注意,arg 有时表示用户空间指针;在其他情况下,它可能只是一个简单的整数值。当 arg 表示用户空间指针时,安全模块永远不应使用它。

返回

如果授予权限,则返回 0。

int security_file_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)

检查是否允许在兼容模式下使用 ioctl

参数

struct file *file

关联文件

unsigned int cmd

ioctl 命令

unsigned long arg

ioctl 参数

描述

security_file_ioctl() 的兼容版本,可以正确处理在 64 位内核上运行的 32 位进程。

返回

如果授予权限,则返回 0。

int security_file_post_open(struct file *file, int mask)

在文件打开后对其进行评估

参数

struct file *file

文件

int mask

访问掩码

描述

评估已打开的文件以及通过 open() 请求的访问掩码。对于需要文件内容才能做出决策的 LSM 来说,此挂钩很有用。

返回

如果授予权限,则返回 0。

void security_cred_getsecid(const struct cred *c, u32 *secid)

从一组凭据中获取 secid

参数

const struct cred *c

凭据

u32 *secid

secid 值

描述

检索 cred 结构 c 的安全标识符。如果失败,secid 将设置为零。

void security_cred_getlsmprop(const struct cred *c, struct lsm_prop *prop)

从一组凭据中获取 LSM 数据

参数

const struct cred *c

凭据

struct lsm_prop *prop

LSM 数据的目标

描述

检索 cred 结构 c 的安全数据。如果失败,prop 将被清除。

int security_kernel_read_file(struct file *file, enum kernel_read_file_id id, bool contents)

读取用户空间指定的文件

参数

struct file *file

文件

enum kernel_read_file_id id

文件标识符

bool contents

如果将调用 security_kernel_post_read_file(),则信任

描述

读取用户空间指定的文件。

返回

如果授予权限,则返回 0。

int security_kernel_post_read_file(struct file *file, char *buf, loff_t size, enum kernel_read_file_id id)

读取用户空间指定的文件

参数

struct file *file

文件

char *buf

文件内容

loff_t size

文件内容的大小

enum kernel_read_file_id id

文件标识符

描述

读取用户空间指定的文件。这必须与先前调用 security_kernel_read_file() 配对,该调用指示也将调用此挂钩,有关更多信息,请参见 security_kernel_read_file()

返回

如果授予权限,则返回 0。

int security_kernel_load_data(enum kernel_load_data_id id, bool contents)

加载用户空间提供的数据

参数

enum kernel_load_data_id id

数据标识符

bool contents

如果将调用 security_kernel_post_load_data(),则为 true

描述

加载用户空间提供的数据。

返回

如果授予权限,则返回 0。

int security_kernel_post_load_data(char *buf, loff_t size, enum kernel_load_data_id id, char *description)

从非文件源加载用户空间数据

参数

char *buf

数据

loff_t size

数据大小

enum kernel_load_data_id id

数据标识符

char *description

数据的文本描述,特定于 id 值

描述

加载非文件源(通常是用户空间缓冲区)提供的数据。这必须与先前的 security_kernel_load_data() 调用配对,该调用指示也将调用此挂钩,有关更多信息,请参见 security_kernel_load_data()

返回

如果授予权限,则返回 0。

void security_current_getlsmprop_subj(struct lsm_prop *prop)

当前任务的主观 LSM 数据

参数

struct lsm_prop *prop

lsm 特定信息

描述

检索当前任务的主观安全标识符,并在 prop 中返回它。

void security_task_getlsmprop_obj(struct task_struct *p, struct lsm_prop *prop)

获取任务的客观 LSM 数据

参数

struct task_struct *p

目标任务

struct lsm_prop *prop

lsm 特定信息

描述

检索 p 中 task_struct 的客观安全标识符,并在 prop 中返回它。

void security_d_instantiate(struct dentry *dentry, struct inode *inode)

基于 dentry 填充 inode 的 LSM 状态

参数

struct dentry *dentry

dentry

struct inode *inode

inode

描述

如果允许,填写 dentryinode 安全信息。

int security_ismaclabel(const char *name)

检查命名的属性是否为 MAC 标签

参数

const char *name

完整的扩展属性名称

描述

检查由 name 指定的扩展属性是否表示 MAC 标签。

返回

如果 name 是 MAC 属性,则返回 1;否则返回 0。

int security_secid_to_secctx(u32 secid, struct lsm_context *cp)

将 secid 转换为 secctx

参数

u32 secid

secid

struct lsm_context *cp

LSM 上下文

描述

将 secid 转换为安全上下文。如果 cp 为 NULL,则将返回结果的长度,但不返回数据。这意味着长度可能会在检查长度的调用和实际分配和返回数据的下一个调用之间发生变化。

返回

成功时返回数据长度,失败时返回错误。

int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp)

将 lsm_prop 转换为 secctx

参数

struct lsm_prop *prop

lsm 特定信息

struct lsm_context *cp

LSM 上下文

描述

prop 条目转换为安全上下文。如果 cp 为 NULL,则将返回结果的长度。这意味着长度可能会在检查长度的调用和实际分配和返回 cp 的下一个调用之间发生变化。

返回

成功时返回数据长度,失败时返回错误。

int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)

将 secctx 转换为 secid

参数

const char *secdata

secctx

u32 seclen

secctx 的长度

u32 *secid

secid

描述

将安全上下文转换为 secid。

返回

成功时返回 0,失败时返回错误。

void security_release_secctx(struct lsm_context *cp)

释放 secctx 缓冲区

参数

struct lsm_context *cp

安全上下文

描述

释放安全上下文。

void security_inode_invalidate_secctx(struct inode *inode)

使 inode 的安全标签无效

参数

struct inode *inode

inode

描述

通知安全模块必须重新验证 inode 的安全上下文。

int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)

将 inode 的安全标签通知给 LSM

参数

struct inode *inode

inode

void *ctx

secctx

u32 ctxlen

secctx 的长度

描述

通知安全模块 inode 的安全上下文应该是什么。初始化由安全模块为此 inode 管理的内核安全上下文。用法示例:NFS 客户端调用此挂钩以将其内核 inode 中的安全上下文初始化为服务器为文件提供的值,当服务器将文件的属性返回给客户端时。必须使用 inode->i_mutex 锁定来调用。

返回

成功时返回 0,失败时返回错误。

int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)

更改 inode 的安全标签

参数

struct dentry *dentry

inode

void *ctx

secctx

u32 ctxlen

secctx 的长度

描述

更改 inode 的安全上下文。更新由安全模块管理的内核安全上下文,并根据需要调用 fs 代码(通过 __vfs_setxattr_noperm)以更新表示上下文的任何后备 xattrs。用法示例:NFS 服务器调用此挂钩以将其内核 inode 和后备文件系统中的安全上下文更改为客户端在 SETATTR 操作上提供的值。必须使用 inode->i_mutex 锁定来调用。

返回

成功时返回 0,失败时返回错误。

int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp)

获取 inode 的安全标签

参数

struct inode *inode

inode

struct lsm_context *cp

安全上下文

描述

成功时,返回 0 并使用给定 inode 的安全上下文填充 cp

返回

成功时返回 0,失败时返回错误。

int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk)

检查是否允许 AF_UNIX 流

参数

struct sock *sock

原始套接字

struct sock *other

对等套接字

struct sock *newsk

新套接字

描述

sockother 之间建立 Unix 域流连接之前,检查权限。

之所以需要 unix_stream_connectunix_may_send 挂钩,是因为 Linux 为 Unix 域套接字提供了一个替代传统文件命名空间的方法。在文件命名空间中绑定和连接到套接字的操作由典型的文件权限进行调解(并由 inode_security_ops 中的 mknod 和权限挂钩捕获),而在抽象命名空间中绑定和连接到套接字的操作完全不受调解。仅使用套接字层挂钩无法充分控制抽象命名空间中的 Unix 域套接字,因为我们需要知道实际目标套接字,该套接字直到我们在 af_unix 代码内部才会被查找。

返回

如果授予权限,则返回 0。

int security_unix_may_send(struct socket *sock, struct socket *other)

检查 AF_UNIX 套接字是否可以发送数据报

参数

struct socket *sock

原始套接字

struct socket *other

对等套接字

描述

在将数据报从 sock 连接或发送到 other 之前,检查权限。

之所以需要 unix_stream_connectunix_may_send 挂钩,是因为 Linux 为 Unix 域套接字提供了一个替代传统文件命名空间的方法。在文件命名空间中绑定和连接到套接字的操作由典型的文件权限进行调解(并由 inode_security_ops 中的 mknod 和权限挂钩捕获),而在抽象命名空间中绑定和连接到套接字的操作完全不受调解。仅使用套接字层挂钩无法充分控制抽象命名空间中的 Unix 域套接字,因为我们需要知道实际目标套接字,该套接字直到我们在 af_unix 代码内部才会被查找。

返回

如果授予权限,则返回 0。

int security_socket_socketpair(struct socket *socka, struct socket *sockb)

检查是否允许创建套接字对

参数

struct socket *socka

第一个套接字

struct socket *sockb

第二个套接字

描述

在创建一对新的套接字之前,检查权限。

返回

如果授予权限并且建立了连接,则返回 0。

已建立。

int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)

检查是否允许传入的网络数据包

参数

struct sock *sk

目标套接字

struct sk_buff *skb

传入数据包

描述

检查传入网络数据包的权限。此挂钩与 Netfilter 的 IP 输入挂钩不同,因为这是传入的 sk_buff skb 首次与特定套接字 sk 关联。在此挂钩内部不能休眠,因为某些调用方持有自旋锁。

返回

如果授予权限,则返回 0。

int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)

获取远程对等标签

参数

struct socket *sock

套接字

struct sk_buff *skb

数据报包

u32 *secid

远程对等标签 secid

描述

此挂钩允许安全模块通过 getsockopt SO_GETPEERSEC 为每个数据包的用户空间提供 udp 套接字的对等套接字安全状态。应用程序必须首先通过 getsockopt 指示 IP_PASSSEC 选项。然后,它可以检索通过 SCM_SECURITY 辅助消息类型从此挂钩返回的数据包的安全状态。

返回

成功时返回 0,失败时返回错误。

void security_sk_clone(const struct sock *sk, struct sock *newsk)

克隆套接字的 LSM 状态

参数

const struct sock *sk

原始套接字

struct sock *newsk

目标套接字

描述

克隆/复制安全结构。

void security_sk_classify_flow(const struct sock *sk, struct flowi_common *flic)

基于套接字设置流的 secid

参数

const struct sock *sk

原始套接字

struct flowi_common *flic

目标流

描述

将目标流的 secid 设置为套接字的 secid。

void security_req_classify_flow(const struct request_sock *req, struct flowi_common *flic)

基于 request_sock 设置流的 secid

参数

const struct request_sock *req

request_sock

struct flowi_common *flic

目标流

描述

flic 的 secid 设置为 req 的 secid。

void security_sock_graft(struct sock *sk, struct socket *parent)

在套接字上嫁接套接字时协调 LSM 状态

参数

struct sock *sk

正在嫁接的套接字

struct socket *parent

目标父套接字

描述

parent 的 inode secid 设置为 sk 的 secid,并使用来自 parent 的任何必要的 LSM 状态更新 sk

int security_inet_conn_request(const struct sock *sk, struct sk_buff *skb, struct request_sock *req)

使用传入的连接设置 request_sock 状态

参数

const struct sock *sk

父监听套接字

struct sk_buff *skb

传入连接

struct request_sock *req

新 request_sock

描述

基于 skskb 中的传入连接初始化 req LSM 状态。

返回

如果授予权限,则返回 0。

void security_inet_conn_established(struct sock *sk, struct sk_buff *skb)

使用连接更新套接字的 LSM 状态

参数

struct sock *sk

套接字

struct sk_buff *skb

连接包

描述

更新 sock 的 LSM 状态以表示来自 skb 的新连接。

int security_secmark_relabel_packet(u32 secid)

检查是否允许设置 secmark

参数

u32 secid

新的 secmark 值

描述

检查是否应允许该进程将数据包重新标记为 secid

返回

如果授予权限,则返回 0。

void security_secmark_refcount_inc(void)

递增 secmark 标记规则计数

参数

void

无参数

描述

告诉 LSM 递增加载的 secmark 标记规则的数量。

void security_secmark_refcount_dec(void)

递减 secmark 标记规则计数

参数

void

无参数

描述

告诉 LSM 递减加载的 secmark 标记规则的数量。

int security_tun_dev_alloc_security(void **security)

为 TUN 设备分配 LSM blob

参数

void **security

指向 LSM blob 的指针

描述

此挂钩允许模块为 TUN 设备分配安全结构,并在 security 中返回指针。

返回

成功时返回零,失败时返回负值。

void security_tun_dev_free_security(void *security)

释放 TUN 设备 LSM blob

参数

void *security

LSM blob

描述

此挂钩允许模块释放 TUN 设备的安全性结构。

int security_tun_dev_create(void)

检查是否允许创建 TUN 设备

参数

void

无参数

描述

在创建新的 TUN 设备之前检查权限。

返回

如果授予权限,则返回 0。

int security_tun_dev_attach_queue(void *security)

检查是否允许附加 TUN 队列

参数

void *security

TUN 设备 LSM blob

描述

在附加到 TUN 设备队列之前检查权限。

返回

如果授予权限,则返回 0。

int security_tun_dev_attach(struct sock *sk, void *security)

在附加时更新 TUN 设备 LSM 状态

参数

struct sock *sk

关联的套接字

void *security

TUN 设备 LSM blob

描述

模块可以使用此挂钩来更新与 TUN 设备的套接字结构关联的任何安全状态。

返回

如果授予权限,则返回 0。

int security_tun_dev_open(void *security)

在打开时更新 TUN 设备 LSM 状态

参数

void *security

TUN 设备 LSM blob

描述

模块可以使用此挂钩来更新与 TUN 设备的安全性结构关联的任何安全状态。

返回

如果授予权限,则返回 0。

int security_sctp_assoc_request(struct sctp_association *asoc, struct sk_buff *skb)

在 SCTP 关联请求时更新 LSM

参数

struct sctp_association *asoc

SCTP 关联

struct sk_buff *skb

请求关联的数据包

描述

将关联的 INIT 数据包的 asocchunk->skb 传递给 LSM。

返回

成功时返回 0,失败时返回错误。

int security_sctp_bind_connect(struct sock *sk, int optname, struct sockaddr *address, int addrlen)

验证 SCTP 选项的地址列表

参数

struct sock *sk

套接字

int optname

要验证的 SCTP 选项

struct sockaddr *address

要验证的 IP 地址列表

int addrlen

地址列表的长度

描述

验证与套接字 sk 关联的每个地址所需的权限。根据 optname,这些地址将被视为连接或绑定服务。使用 sizeof(struct sockaddr_in) 或 sizeof(struct sockaddr_in6) 在每个 IPv4 和 IPv6 地址上计算 addrlen

返回

成功时返回 0,失败时返回错误。

void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, struct sock *newsk)

克隆 SCTP 套接字的 LSM 状态

参数

struct sctp_association *asoc

SCTP 关联

struct sock *sk

原始套接字

struct sock *newsk

目标套接字

描述

每当通过 accept(2) 创建新套接字(即 TCP 样式套接字)或套接字被“剥离”时调用,例如用户空间调用 sctp_peeloff(3)。

int security_sctp_assoc_established(struct sctp_association *asoc, struct sk_buff *skb)

关联建立时更新 LSM 状态

参数

struct sctp_association *asoc

SCTP 关联

struct sk_buff *skb

建立关联的数据包

描述

将关联的 COOKIE_ACK 数据包的 asocchunk->skb 传递给安全模块。

返回

如果授予权限,则返回 0。

int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)

检查是否允许访问 IB pkey

参数

void *sec

LSM blob

u64 subnet_prefix

端口的子网前缀

u16 pkey

IB pkey

描述

检查在修改 QP 时访问 pkey 的权限。

返回

如果授予权限,则返回 0。

int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)

检查是否允许 SMPs 流量

参数

void *sec

LSM blob

const char *dev_name

IB 设备名称

u8 port_num

端口号

描述

检查在端端口上发送和接收 SMP 的权限。

返回

如果授予权限,则返回 0。

int security_ib_alloc_security(void **sec)

分配 Infiniband LSM blob

参数

void **sec

LSM blob

描述

为 Infiniband 对象分配安全结构。

返回

成功时返回 0,失败时返回非零值。

void security_ib_free_security(void *sec)

释放 Infiniband LSM blob

参数

void *sec

LSM blob

描述

取消分配 Infiniband 安全结构。

int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp)

分配 xfrm 策略 LSM blob

参数

struct xfrm_sec_ctx **ctxp

正在添加到 SPD 的 xfrm 安全上下文

struct xfrm_user_sec_ctx *sec_ctx

用户空间提供的安全标签

gfp_t gfp

gfp 标志

描述

为 xp->security 字段分配安全结构;当分配 xfrm_policy 时,安全字段初始化为 NULL。

返回

如果操作成功,则返回 0。

void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx)

释放 xfrm 安全上下文

参数

struct xfrm_sec_ctx *ctx

xfrm 安全上下文

描述

释放与 ctx 关联的 LSM 资源。

int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)

分配 xfrm 状态 LSM blob

参数

struct xfrm_state *x

正在添加到 SAD 的 xfrm 状态

struct xfrm_user_sec_ctx *sec_ctx

用户空间提供的安全标签

描述

x->security 字段分配安全结构;当分配 xfrm_state 时,安全字段初始化为 NULL。将上下文设置为对应于 sec_ctx

返回

如果操作成功,则返回 0。

int security_xfrm_state_delete(struct xfrm_state *x)

检查是否允许删除 xfrm 状态

参数

struct xfrm_state *x

xfrm 状态

描述

授权删除 x->security。

返回

如果授予权限,则返回 0。

int security_locked_down(enum lockdown_reason what)

检查是否允许内核功能

参数

enum lockdown_reason what

请求的内核功能

描述

确定是否应允许潜在地在内核空间中启用任意代码执行的内核功能。

返回

如果授予权限,则返回 0。

int security_bdev_alloc(struct block_device *bdev)

分配块设备 LSM blob

参数

struct block_device *bdev

块设备

描述

分配安全结构并将其附加到 bdev->bd_security。当分配 bdev 结构时,安全字段初始化为 NULL。

返回

如果操作成功,则返回 0。

void security_bdev_free(struct block_device *bdev)

释放块设备的 LSM blob

参数

struct block_device *bdev

块设备

描述

取消分配 bdev 安全结构并将 bdev->bd_security 设置为 NULL。

int security_bdev_setintegrity(struct block_device *bdev, enum lsm_integrity_type type, const void *value, size_t size)

设置设备的完整性数据

参数

struct block_device *bdev

块设备

enum lsm_integrity_type type

完整性的类型,例如哈希摘要、签名等

const void *value

完整性值

size_t size

完整性值的大小

描述

向 LSM 注册 bdev 的经过验证的完整性测量。如果 value 为 NULL,LSM 应释放先前保存的数据。请注意,每次更新安全信息时都应调用新挂钩,以使这些数据保持最新。例如,在 dm-verity 中,如果重新加载映射表并配置为使用具有新 roothash 和签名信息的不同 dm-verity 目标,则 LSM blob 中先前存储的数据将变得过时。重新调用挂钩以刷新这些数据并确保它们是最新的至关重要。这种必要性源于设备映射器的设计,其中首先创建一个设备映射器设备,然后将目标加载到其中。这些目标可以在设备的生命周期内多次修改。因此,虽然在创建块设备期间分配了 LSM blob,但其实际内容并未在此阶段初始化,并且可能会随着时间的推移发生重大变化。这包括从 LSM“信任”的数据到他们不信任的数据的更改,因此必须正确处理这些更改。未能解决这种动态方面可能会允许绕过 LSM 检查。

返回

成功时返回 0,失败时返回负值。