Linux audit子系统对文件的审计有三套方案。第一套使用文件的inode号,第二套使用文件的路径名,第三套使用目录的路径名。
1.使用inode号审计文件
来看一下规则匹配的代码:
在audit context中逐一匹配规则中存储的inode号。
2.使用文件的路径名审计文件
使用文件的路径名来审计文件依赖关键数据结构audit_watch。在audit_filter_rules函数中有下面这段语句:
audit_watch_compare的函数实现是:
看起来和前面的基于inode号的方案没有什么区别,也是比较inode号。奥妙在于watch中的ino的值可以是“-1”,表示这个watch还未生效。watch的生效依赖于另一个数据类型——audit_parent:(www.xing528.com)
audit_parent只有两个成员,一个是fsnotify mark,另一个是list,串起相关的watch。audit_parent对应一个目录,audit_watch对应一个文件。当用户为一个文件创建一个audit watch时,这个audit watch就被串入audit parent的watches链表中。audit watch的神奇之处在于用户可以为还不存在的文件创建watch。做到这一点,需要audit_parent中的类型为fsnotify_mark的成员mark。
fsnotify是Linux内核中的一个机制,audit依靠它在文件发生变化时得到通知。当目录下有文件创建或删除时,audit_watch_handle_event就会被调用。当文件创建时,audit_watch中的ino会被更新为实际的文件ino号;当文件被删除时,audit_watch中的ino会被赋值为表示无效的“-1”
3.使用目录的路径名来审计文件
使用目录的路径名审计文件依赖关键数据结构audit_tree。如果用audit_watch审计一个目录下的所有文件,那么就需要建立许多条审计规则。即使如此,仍然无法对还不存在并且不知道名字的文件实行审计。audit_watch只能对知道名字但还不存在的文件建立审计规则。这种情况就需要audit_tree了。
audit子系统设计了两个结构体:audit_tree和audit_chunk。在逻辑上是一个tree包含若干chunk。tree代表目录树,那chunk呢?chunk这个英文单词的意思是“一大块”,这个单词多半是trunk(意思为树干)的误用。可能audit_tree.c的作者是个母语非英语的程序员。
目录树的概念比较容易理解。“树干”是什么呢?“树干”就是文件系统的挂载点。在建立一条包含目录的审计规则时,内核audit子系统会构建一个audit_tree实例,同时循目录遍历,一遇到挂载点就构建audit_chunk实例,并将其关联到audit_tree中。在涉及文件的系统调用中内核audit系统的钩子函数会查询文件所在文件系统的挂载点,将其记录到进程的audit_context中。在系统调用结束时,对audit_context进行检查。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。