原标题:Linux安全审计机制模块实现分析(8)
3.进程审计钩子函数举例
下面以 hook 函数 audit_bprm为例,说明内核函数的审计记录过程。当进程执行一个二进制文件时,它调用系统调用 sys_execve完成执行应用程序操作。函数 sys_execve调用 hook函数 audit_bprm的调用层次图如下图所示:
图2-20 audit_bprm函数的被调层次图
hook 函数 audit_bprm获取执行应用程序参数信息,审计消息对应的消息类型为AUDIT_EXECVE,其消息类型定义如下:
#define AUDIT_EXECVE 1309
(1)audit_bprm接口功能说明
函数名:audit_bprm
参数:linux_binprm为可执行文件相关信息。
返回值:成功获取信息返回0.
功能:截获程序执行的参数信息并拷贝到派生辅助数据结构audit_aux_data_execve 中
(2)函数分析
结构 linux_binprm 含有装载二进制文件的信息,如:文件名、程序执行的参数和环境变量等。函数audit_bprm将程序执行的参数信息拷贝到派生辅助数据结构audit_aux_data_execve中,并将该结构链接到审计上下文的辅助数据链表中。其处理流程如下图:
图 2-21 audit_bprm函数流程图
2.3.5 文件系统的审计2.3.5.1文件系统变化监视机制
1.主要数据结构
在fsnotify机制中抽象出如下几个数据结构:
fsnotify_event----文件系统发生的具体的变化,比如文件的打开事件,读写事件,删除事件等等,在具体事件发生时创建该结构的实例。
fsnotify_mark----用户创建的文件系统监视,该结构实例是对文件或目录打上的一个标记,该文件或目录的某些变化将受到fsnotify机制的监视。监视实例以目录为组织单位进行管理,一个目录下的所有的文件监视实例的链表被嵌入该目录对应的索引节点结构中。
fsnotify_group---处理事件的策略,用户每创建一个对文件或目录的监视mark-实例,必须指定一个fsnotify_group类型的实例group,在该文件发生用户关心的某些变化(即发生了某些event)时,将会调用fsnotify_group指定的事件处理函数进行处理。
fsnotify_mark结构列出如下:
struct fsnotify_mark {
__u32 mask;/* 事件掩码,表示要监视哪些事件 */
atomic_t refcnt;/* 引用数 */
struct fsnotify_group *group;/*为监视指定的group,用于处理监视到的事件*/
struct list_head g_list;/*用于链接同一个目录下的所有监视实例*/
spinlock_t lock;
union {
struct fsnotify_inode_mark i; /*如果监视的是inode,在这里记录监视数据*/
struct fsnotify_vfsmount_mark m;/*如果监视的是vfsmount,在这里记录监视数据
};
struct list_head free_g_list;/* 用于释放该结构的空闲链表 */
__u32 ignored_mask;
unsigned int flags;/* 监视的时inode还是vfsmount? */
struct list_head destroy_list;
void (*free_mark)(struct fsnotify_mark *mark); /*释放函数*/
};
fsnotify_group结构的主要成员列出如下:
struct fsnotify_group {
……..
atomic_t refcnt;/* 引用数 */
const struct fsnotify_ops *ops;/* 用于事件处理的函数*/
unsigned int max_events;/* 允许处理的最大事件数 */
struct list_head marks_list;/*由该group处理的所有mark */
……..;
};
fsnotify_event结构的主要成员列出如下:
struct fsnotify_event {
……..;
struct inode *to_tell;/*发生事件的索引节点或父索引节点 */
union {
struct path path; /*发生事件的是目录*/
struct inode *inode; /*发送事件的是文件*/
};
int data_type;/*发生事件的是目录还是文件 */
atomic_t refcnt;/* 引用数*/
const unsigned char *file_name; /*文件名*/
struct list_head private_data_list;/* group可以利用此结构存放私有数据 */
};
2 给文件或目录打上监视的标记
被fsonotify所监视的文件或目录,都需要在inode的>i_fsnotify_marks链表上添加一个mark元素。该过程首先利用fsnotify_init_mark函数初始化一个mark实例,然后调用Fsnotify_add_mark函数给inode添加mark。Fsnotify_add_mark函数的工作流程如下:
1.给mark指定一个group,并把mark挂到group的mark链表上
2.如果是mark监视的是inode,将mark的标记设置为FSNOTIFY_MARK_FLAG_INODE,并在mark中记录下inode的信息,然后将mark挂到inode存放所有监视该inode的所有mark实例的链表inode->i_fsnotify_marks上。如果否,转3.
3.将mark的标记设置为FSNOTIFY_MARK_FLAG_VFSMOUNT,并用和步骤2类似的步骤将mark和vfsmount关联起来。
3监视文件系统的钩子函数
为监视文件系统的变化,文件系统的各个操作函数中加入了hook 函数,当文件系统调用了这些操作函数改变了文件系统中的文件或目录时,就调用hook函数发出相应的事件。文件系统部分钩子函数如下表2-4 。
表2-4 文件系统审计的部分钩子函数
函数名
被放置的地点
作用
fsnotify_parent
在读、写、关闭文件的函数中
给父目录项通知孩子节点的变化
fsnotify_d_move
移动一个目录项的函数中
通知目录项的移动
fsnotify_link_count
取消链接的函数中
通知链接引用数的减少
fsnotify_move
重命名的函数中
通知重命名事件
fsnotify_inode_delete
Inode从缓存中销毁函数中
通知索引节点的变化
fsnotify_nameremove
文件名从目录删除的函数中
通知给父目录项通知孩子节点的变化
fsnotify_create
创建文件或符号链接或设备节点等的函数中
获取执行该程序的信息
当钩子函数截获到相关变化时,由fsnotify函数把相关变化转换成事件的形式转发给事件被注册的监视处理实例,再由监视处理实例调用事件处理函数完成审计处理(由于本文的重点是文件系统审计监视,而非一般意义的文件系统监视,所以该函数不作详细的分析)。
责任编辑: