Linux 安全 - LSM hook点

文章目录

  • 一、LSM file system hooks
    • 1.1 LSM super_block hooks
    • 1.2 LSM file hooks
    • 1.3 LSM inode hooks
  • 二、LSM Task hooks
  • 三、LSM IPC hooks
  • 四、LSM Network hooks
  • 五、LSM Module & System hooks

一、LSM file system hooks

在VFS(虚拟文件系统)层中,定义了三个主要对象,它们封装了低级文件系统开发所使用的接口:

super_block(超级块)对象
file(文件)对象
inode(索引节点)对象

每个对象都包含一组操作,这些操作定义了VFS与实际文件系统之间的接口。LSM(Linux安全模块)利用这些接口来介入文件系统访问。

LSM使用内核对象中定义的不透明安全指针:

super_block(超级块)结构体
file(文件)结构体
inode(索引节点)结构体

通过在这些结构体中添加安全指针,LSM可以监视和控制与文件系统相关的操作。这样,LSM可以在文件系统访问过程中介入,执行安全策略检查、权限控制等操作,以增强系统的安全性。

1.1 LSM super_block hooks

struct super_block {
	......
#ifdef CONFIG_SECURITY
	void                    *s_security;
#endif
	.....
}

当文件系统在内核中表示时,super_block 结构体是代表该文件系统的内核对象。

super_block 结构体在挂载和卸载文件系统以及获取文件系统统计信息时被使用。

LSM(Linux安全模块)提供了一组钩子函数,用于介入对 super_block 的各种操作。

在挂载文件系统时,内核首先通过调用 sb_mount() 钩子函数来验证挂载请求的有效性。LSM可以使用该钩子函数执行额外的安全检查,例如验证挂载任务的权限或确保挂载选项的有效性。

在卸载文件系统时,会调用 sb_umount() 钩子函数来检查卸载文件系统所需的权限。LSM可以利用这个钩子函数来执行访问控制,确保只有授权的任务能够执行卸载操作。

sb_remount() 钩子函数在修改文件系统挂载选项时被调用。LSM可以利用该钩子函数验证请求的挂载选项的有效性和安全性。

当任务尝试获取文件系统统计信息(如磁盘使用情况或可用空间)时,会调用 sb_statfs() 钩子函数。LSM可以使用该钩子函数执行权限检查,确保只有授权的任务能够访问文件系统统计信息。

union security_list_options {
	......
	int (*sb_remount)(struct super_block *sb, void *mnt_opts);
	int (*sb_statfs)(struct dentry *dentry);
	int (*sb_mount)(const char *dev_name, const struct path *path,
			const char *type, unsigned long flags, void *data);
	int (*sb_umount)(struct vfsmount *mnt, int flags);
	......
}

通过介入对 super_block 结构体及其相关操作的访问,LSM在强制安全措施、验证权限和控制文件系统操作方面发挥着重要作用。它可以执行安全策略检查、增强访问控制,并确保文件系统的完整性和安全性。

1.2 LSM file hooks

当文件在内核中表示为打开文件时,file 结构体是代表该文件的内核对象。

file 结构体包含了关于文件的信息,如文件位置、访问模式和与文件相关的数据。

在 file 结构体中,有一个 file_operation 结构体,描述了可以对文件执行的操作。这些操作包括从文件中读取数据、向文件写入数据、寻址文件、将文件映射到内存等等。

LSM(Linux安全模块)提供了一组文件钩子函数,用于介入对文件的访问。

file_permission() 钩子函数用于在每次文件读取和写入操作时重新验证读写权限。LSM可以利用该钩子函数执行额外的权限检查,确保尝试读取或写入文件的任务具有必要的权限。

file_locks() 钩子函数用于在使用锁来同步多个读取器或写入器访问文件时。任务在执行任何文件锁定操作之前必须通过 file_locks() 钩子函数的权限检查。该钩子函数使LSM能够执行访问控制,防止未经授权的锁定操作。

file_ioctl() 和 file_fcntl() 钩子函数用于处理通过 ioctl(2) 和 fcntl(2) 系统调用发起的各种杂项文件操作。这些钩子函数使LSM能够介入和控制各种文件相关操作,例如设置文件属性、控制文件行为或执行特定于某些文件类型的特殊操作。

通过介入对 file 结构体及其相关操作的访问,LSM在强制安全措施、验证权限和控制文件访问方面发挥着重要作用。它能够执行安全策略检查,增强访问控制,并确保系统内文件操作的完整性和安全性。

1.3 LSM inode hooks

inode 结构体是表示内核文件对象(如文件、目录或符号链接)的内核对象。

当文件系统中的文件、目录或符号链接在内核中被表示时,inode 结构体就扮演着代表其元数据的角色。

LSM(Linux安全模块)提供了一组钩子函数,用于介入对 inode 结构体的访问。

内核的 inode 缓存通过文件查找操作(例如打开文件)或文件系统对象创建操作(例如创建新文件或目录)填充。

LSM可以利用这些钩子函数来介入对 inode 结构体的访问,并对其上执行的操作进行调控。这些钩子函数允许LSM执行安全策略检查、权限控制以及对文件系统对象的访问控制。

LSM提供的与 inode 操作相关的钩子函数包括:
(1)文件的创建和删除:在创建或删除文件、目录或其他文件系统对象时调用的钩子函数,例如 create()、mkdir()、rmdir()、mknod() 和 rename()。

(2)链接和解除链接:用于创建或删除硬链接或符号链接时调用的钩子函数,例如 link()、unlink()、symlink()、readlink() 和 follow_link()。

(3)属性操作:用于获取或修改文件属性、扩展属性和权限的钩子函数,例如 getattr()、setattr()、getxattr()、setxattr() 和 permissions()。

在这些钩子函数中,LSM可以执行各种与安全相关的任务,例如验证权限、强制访问控制策略、审计文件操作,并根据文件的属性和请求的操作应用其他安全检查。

通过介入对 inode 结构体及其关联操作的访问,LSM在增强文件系统的安全性方面发挥着关键作用。它通过实施细粒度的访问控制和确保符合安全策略来提高文件系统的安全性。

二、LSM Task hooks

当任务在内核中表示为可调度任务时,task_struct 结构体是代表该任务的内核对象。

task_struct 结构体包含了任务的基本信息,如用户/组 ID、资源限制以及调度策略和优先级等。

LSM(Linux安全模块)提供了一组任务钩子函数,用于介入任务对基本任务信息的访问。

task_alloc() 钩子函数用于验证任务是否可以创建子任务。当任务尝试创建子任务时,LSM可以利用该钩子函数执行额外的检查,例如验证任务的权限或强制执行与任务创建相关的特定策略。

task_kill() 钩子函数在任务退出或被终止时被调用。LSM可以使用该钩子函数执行清理操作、释放任何已持有的资源或记录相关信息,然后再终止任务。

在任务的生命周期中,一些信息可能会发生变化。例如,当任务调用 setuid(2) 等系统调用来更改其用户 ID 时,会触发 task_fix_setuid() 钩子函数。LSM可以拦截这类调用,并执行额外的操作或检查,以确保任务状态的安全性和完整性。

通过使用这些任务钩子函数,LSM可以对任务对基本任务信息的访问进行控制。它能够执行安全策略检查、验证权限,并控制任务相关操作。

通过任务钩子函数,LSM增强了系统的安全性和稳定性。它能够强制访问控制,验证权限,并执行必要的操作,以保持任务相关操作的完整性。

三、LSM IPC hooks

当任务需要访问内核中的 SysV IPC 机制时,内核提供了标准的 SysV IPC 机制,包括共享内存、信号量和消息队列等。这些机制允许进程之间进行通信和共享数据。

LSM(Linux安全模块)为这些 IPC 机制提供了一组钩子函数,用于介入对内核 IPC 对象的访问。这些钩子函数使得 LSM 能够执行安全策略检查、验证权限,并控制与 IPC 对象相关的操作。

ipc_permission() 钩子函数用于检查 IPC 对象的权限。当进程尝试访问 IPC 对象(如共享内存、信号量或消息队列)时,LSM 可以使用该钩子函数验证进程是否具有执行所请求操作的必要权限。

msg_queue_msgrcv() 钩子函数在消息从消息队列中被移除之前进行调用。LSM 可以使用该钩子函数检查权限,确保只有授权的进程才能读取或删除消息队列中的消息。

shm_shmat() 钩子函数在执行 shmat(2) 系统调用之前进行调用,该调用将共享内存段附加到调用进程的数据段。LSM 可以利用该钩子函数检查权限,只允许具有适当权限的进程访问共享内存。

sem_semctl() 钩子函数在对信号量执行指定命令的操作之前进行调用。LSM 可以使用该钩子函数检查权限,并确保只有具有必要权限的进程才能对信号量执行指定的操作。

通过这些 IPC 钩子函数,LSM 增强了对内核 IPC 对象的访问控制和安全性。它可以执行安全策略检查,验证权限,并控制与共享内存、信号量和消息队列相关的操作。

通过 IPC 钩子函数,LSM 可以进行安全性检查、权限验证,并确保系统内 IPC 操作的完整性和安全性。这有助于防止未经授权的访问,强制执行访问控制,并维护系统的安全性和稳定性。

四、LSM Network hooks

网络是Linux中的一个重要方面,尤其是在保护系统免受网络攻击方面,LSM为内核的这个领域提供了扩展的安全性。应用层对网络的访问是通过一系列与套接字相关的钩子函数进行介入的。

针对所有套接字系统调用提供了钩子函数:

bind()connect()listen()accept()sendmsg()recvmsg()getsockname()getpeername()getsockopt()等等。

网络数据通过sk_buff结构在网络栈中传输,LSM为sk_buff提供了不透明的安全字段,以便可以在每个数据包的基础上跨网络层管理安全状态。

LSM通过提供针对网络相关操作的钩子函数,为内核中的网络部分提供了扩展的安全性。通过这些钩子函数,LSM可以介入应用程序层对网络的访问,验证权限,执行安全策略,并控制与套接字相关的系统调用。

钩子函数包括bind()、connect()、listen()、accept()、sendmsg()、recvmsg()、getsockname()、getpeername()、getsockopt()等套接字系统调用。通过这些钩子函数,LSM可以对套接字操作进行安全策略检查、权限验证和控制。

此外,LSM还为不同的网络协议(如IPv4、Unix域、Netlink、InfiniBand和SCTP)实现了更细粒度的钩子函数。这样可以根据不同协议的特性和需求,对网络操作进行更精细的控制和安全策略管理。

在网络数据传输过程中,数据以sk_buff结构的形式在网络栈中进行封装和传递。LSM为sk_buff提供了不透明的安全字段,以便可以在每个数据包的基础上管理安全状态。这样可以确保安全状态在网络层的各个环节中得到维护和传递,从而增强系统对网络攻击的防护能力。

五、LSM Module & System hooks

LSM提供了一个模块化框架,用于增强Linux内核的安全性。它允许集成多个安全模块,每个模块都实现自己的安全策略和机制。

LSM的一个关键方面是能够介入内核模块的加载和卸载过程。这确保只有经过授权和可信任的模块可以加载到内核中,防止未经授权的代码执行和潜在的安全漏洞。

LSM为处理密钥管理操作定义了专门的钩子。这些钩子使LSM模块能够在涉及基于密钥的操作时执行安全策略和权限检查,例如加密、解密和身份验证。

除了密钥管理,LSM还为其他各种关键操作定义了钩子。这包括检查更改系统时间的权限、分配新的虚拟内存映射的权限、访问内核消息环的权限等。通过在这些关键点执行安全检查,LSM有助于防止未经授权或恶意操作,以保护系统的完整性。

LSM与Linux审计框架集成,通过提供钩子函数,允许安全模块参与审计过程。这使得安全相关事件的记录和监控成为可能,有助于系统分析和取证调查。

LSM还扩展了对使用扩展伯克利数据包过滤器(eBPF)及其相关程序的支持。LSM定义了钩子,允许安全模块对使用eBPF程序的策略和限制进行执行,确保eBPF代码的安全和受控执行。

此外,LSM还包括了一组杂项钩子,用于保护上述特定钩子未涵盖的其他安全敏感操作。这些钩子为各种系统活动提供了额外的保护层,确保全面的安全覆盖。

LSM的灵活性和模块化使其成为增强Linux内核安全性的强大框架。通过支持模块加载、密钥管理、关键操作、审计、eBPF集成等功能,LSM能够执行细粒度的安全策略,并帮助保护系统免受各种威胁和攻击。

你可能感兴趣的:(系统安全,linux,c语言,系统安全)