Linux基于文件扩展属性的执行控制设计文档 一. 总体设计 1.1 设计目标 实现基于文件扩展属性(xattr)的执行控制系统,通过安全标记控制应用程序执行和动态库加载,确保只有授权文件可以执行,并自动管理文件标记状态。 1.2 架构设计 1.3 安全标记设计 授权标记:security.execctrl=verified 未授权标记:security.execctrl=none 所有系统初始文件默认标记为verified 新创建/修改文件自动标记为none 二. 核心模块设计 2.1 LSM模块框架 static struct security_hook_list execctrl_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_check_security, execctrl_bprm_check), LSM_HOOK_INIT(file_mprotect, execctrl_file_mprotect), LSM_HOOK_INIT(inode_init_security, execctrl_inode_init), LSM_HOOK_INIT(file_rename, execctrl_file_rename), LSM_HOOK_INIT(file_close, execctrl_file_close), LSM_HOOK_INIT(task_alloc, execctrl_task_alloc), LSM_HOOK_INIT(file_open, execctrl_file_open), }; static int __init execctrl_init(void) { security_add_hooks(execctrl_hooks, ARRAY_SIZE(execctrl_hooks), "execctrl"); pr_info("Execution control module initialized\n"); return 0; } security_initcall(execctrl_init); 2.2 执行控制模块 执行检查逻辑: 关键函数: static int execctrl_bprm_check(struct linux_binprm *bprm) { struct inode *inode = file_inode(bprm->file); char *value; int rc; // 获取文件安全标记 value = get_xattr(inode, "security.execctrl"); if (value && strcmp(value, "verified") == 0) { // 授权文件:允许执行并标记进程可信 set_bprm_trusted(bprm); kfree(value); return 0; } if (current->execctrl_trusted) { // 可信进程执行未授权文件:临时允许 kfree(value); return 0; } // 其他情况拒绝执行 kfree(value); return -EPERM; } 2.3 动态库加载控制 static int execctrl_file_mprotect(struct vm_area_struct *vma, Unsigned long reqprot, unsigned long prot) { if (prot & PROT_EXEC) { struct file *file = vma->vm_file; if (file) { struct inode *inode = file_inode(file); char *value = get_xattr(inode, "security.execctrl"); if (!(value && strcmp(value, "verified") == 0)) { kfree(value); return -EPERM; // 拒绝加载未授权库 } kfree(value); } } return 0; } 2.4 文件状态监控 2.4.1 新文件创建 static int execctrl_inode_init(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) { // 所有新文件自动标记为none set_xattr(inode, "security.execctrl", "none", 4); return 0; } 2.4.2 文件重命名/移动 static int execctrl_file_rename(struct file *file, struct dentry *old_dentry, struct dentry *new_dentry) { struct inode *inode = d_inode(old_dentry); // 重命名后文件标记为none set_xattr(inode, "security.execctrl", "none", 4); return 0; } 2.4.3 文件修改检测 static void execctrl_file_close(struct file *file) { struct inode *inode = file_inode(file); if (file->f_mode & FMODE_WRITER) { struct timespec64 mtime = inode_get_mtime(inode); // 比较修改时间判断内容是否变化 if(timespec64_compare(&mtime,&file->f_opened_mtime) != 0) { set_xattr(inode,"security.execctrl","none",4); } } } 2.5 标记继承与临时执行 2.5.1 进程可信标记 struct task_security { u32 sid; bool trusted; // 是否可信进程 }; static int execctrl_task_alloc(struct task_struct *task, unsigned long clone_flags) { struct task_security *tsec = current->security; if (tsec) { task->security = kmemdup(tsec, sizeof(*tsec), GFP_KERNEL); if (task->security) return 0; } return -ENOMEM; } 2.5.2 临时文件执行 可信进程创建的临时文件可在该进程上下文中执行: // 在执行检查中 if (current->execctrl_trusted) { // 允许可信进程执行未授权文件 return 0; } 三.脚本执行控制 3.1控制策略 3.2实现机制 static int execctrl_bprm_check(struct linux_binprm *bprm) { // 检查解释器文件 ... // 对于脚本解释器,检查第一个参数(脚本文件) if (is_script_interpreter(bprm->filename)) { struct filename *script = get_script_name(bprm); if (script) { struct path path; if (!kern_path(script->name, LOOKUP_FOLLOW, &path)) { struct inode *inode = d_backing_inode(path.dentry); char *value = get_xattr(inode, "security.execctrl"); if (!(value && strcmp(value, "verified") == 0)) { path_put(&path); kfree(value); return -EPERM; } kfree(value); path_put(&path); } } } ... } 3.3管道和重定向处理 // 在文件打开时检查 static int execctrl_file_open(struct file *file) { if (is_script_interpreter(current->comm) && (file->f_flags & O_RDONLY)) { char *value = get_xattr(file_inode(file), "security.execctrl"); // 如果解释器以只读方式打开文件且文件未授权 if (value && strcmp(value, "none") == 0) { // 检查打开目的(执行或读取) if (is_exec_intent(current)) { kfree(value); return -EPERM; } } kfree(value); } return 0; } 四. 初始化和用户空间工具 4.1 系统初始化 1.模块加载时遍历系统目录设置初始标记: find /usr/bin /bin /sbin /lib -type f -exec setfattr -n security.execctrl -v verified {} \; 2.内核启动时加载LSM模块 4.2 用户空间工具 提供execctrlctl管理工具: # 设置文件标记 execctrlctl set-verified /path/to/file execctrlctl set-none /path/to/file # 查询文件状态 execctrlctl status /path/to/file # 恢复系统初始状态 execctrlctl init-system # 查看可信进程 execctrlctl list-trusted 五.性能与安全考虑 5.1 性能优化 XAttr缓存机制:缓存常用文件的标记状态 可信进程列表优化:使用PID命名空间隔离 异步标记更新:非关键路径使用工作队列 批量处理:系统初始化时批量设置标记 5.2 安全加固 防止标记篡改:设置XAttr只读标志 可信进程链验证:验证父进程可信状态 完整性保护:结合IMA/EVM进行扩展属性签名 特权进程限制:root用户操作需通过安全审计 六. 测试方案 6.1 测试用例 6.2 测试方法 内核模块单元测试(KUnit): 验证各个LSM钩子的正确行为 测试边界条件和错误处理 用户空间集成测试(LTP扩展): 文件创建、修改、重命名操作后的标记状态 各种执行场景的权限验证 性能压测: fork-exec密集场景性能分析 文件操作对系统性能的影响 安全测试: 尝试绕过控制机制的各种方法 特权用户操作的安全性验证 七. 兼容性考虑 7.1 文件系统支持 原生支持:ext4、XFS、Btrfs FUSE支持:通过用户空间代理实现 网络文件系统:NFSv4+(支持扩展属性) 7.2 发行版适配 DKMS模块包:支持主流内核版本 Systemd服务集成:开机自动初始化 SELinux/AppArmor兼容模式 7.3 硬件支持 ARM架构:支持32/64位ARM处理器 x86架构:支持传统BIOS和UEFI启动 虚拟化环境:KVM、Xen、Docker支持 八.未解决问题 脚本的管道和重定向执行控制。 文件内容变化的精确检测(采用mtime/size比较,存在误判)。

视频信息