Linux 安全模块开发

基于 https://lore.kernel.org/r/[email protected],一个新的 LSM 被内核接受,当其意图(描述其试图防止的内容以及在哪些情况下可以预期使用它)在 Documentation/admin-guide/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, void **ctx, u32 *ctxlen)

执行 dentry 初始化

参数

struct dentry *dentry

要初始化的 dentry

int mode

用于确定资源类型的模式

const struct qstr *name

最后一个路径组件的名称

const char **xattr_name

security/LSM xattr 的名称

void **ctx

指向生成的 LSM 上下文的指针

u32 *ctxlen

ctx 的长度

描述

计算 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

要修改的凭据

描述

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

返回

成功返回 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

用于写入扩展属性的回调函数

void *fs_data

文件系统特定的数据

描述

获取要在新创建的 inode 上设置的安全属性名称后缀和值,并为新 inode 设置核心安全字段。此钩子由文件系统代码在 inode 创建事务期间调用,并提供 inode 的原子标签,这与 VFS 调用的 post_create/mkdir/... 钩子不同。

钩子函数应通过调用 lsm_get_xattr_slot() 来检索安全模块保留的槽位,该槽位使用 lsm_blob_sizes 结构的 lbs_xattr_count 字段填充 xattrs 数组。对于每个槽位,钩子函数应将 ->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 名称

描述

当联合文件从下层复制到联合/overlay 层时,过滤正在复制的 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 值

描述

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

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

从一组凭据中获取 LSM 数据

参数

const struct cred *c

凭据

struct lsm_prop *prop

LSM 数据的目标位置

描述

检索凭据结构 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

描述

如果允许,则填充 inodedentry 安全信息。

int security_ismaclabel(const char *name)

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

参数

const char *name

完整的扩展属性名称

描述

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

返回

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

int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)

将 secid 转换为 secctx

参数

u32 secid

secid

char **secdata

secctx

u32 *seclen

secctx 长度

描述

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

返回

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

int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen)

将 lsm_prop 转换为 secctx

参数

struct lsm_prop *prop

lsm 特定信息

char **secdata

secctx

u32 *seclen

secctx 长度

描述

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

返回

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

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(char *secdata, u32 seclen)

释放 secctx 缓冲区

参数

char *secdata

secctx

u32 seclen

secctx 的长度

描述

释放安全上下文。

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)

通知 LSM 一个 inode 的安全标签

参数

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 的安全上下文。更新由安全模块管理的内存中的安全上下文,并根据需要(通过 __vfs_setxattr_noperm)调用 fs 代码,以更新表示上下文的任何支持 xattrs。用法示例:NFS 服务器调用此钩子,以将其内存中的 inode 和底层文件系统中的安全上下文更改为客户端在 SETATTR 操作中提供的值。必须在 inode->i_mutex 被锁定的情况下调用。

返回

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

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

获取 inode 的安全标签

参数

struct inode *inode

inode

void **ctx

secctx

u32 *ctxlen

secctx 的长度

描述

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

返回

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

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

检查是否允许 AF_UNIX 流

参数

struct sock *sock

源 sock

struct sock *other

对等 sock

struct sock *newsk

新的 sock

描述

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

源 sock

struct socket *other

对等 sock

描述

在从 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

目标 sock

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)

克隆 sock 的 LSM 状态

参数

const struct sock *sk

原始 sock

struct sock *newsk

目标 sock

描述

克隆/复制安全结构。

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)

在将 sock 嫁接到 socket 上时协调 LSM 状态

参数

struct sock *sk

正在嫁接的 sock

struct socket *parent

目标父 socket

描述

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

父侦听 sock

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)

使用连接更新 sock 的 LSM 状态

参数

struct sock *sk

sock

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 的指针

描述

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

返回

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

void security_tun_dev_free_security(void *security)

释放 TUN 设备 LSM blob

参数

void *security

LSM blob

描述

此 hook 允许模块释放 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

关联的 sock

void *security

TUN 设备 LSM blob

描述

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

返回

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

int security_tun_dev_open(void *security)

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

参数

void *security

TUN 设备 LSM blob

描述

模块可以使用此 hook 更新与 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

地址列表的长度

描述

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

返回

成功返回 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

原始 sock

struct sock *newsk

目标 sock

描述

当通过 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 数据包的 **asoc** 和 **chunk->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 不信任的数据,因此必须正确处理这些更改。未能解决这种动态方面可能会允许绕过 LSM 检查。

返回

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