文件管理器安全管理功能设计

在文件管理器的安全管理部分,我们需要实时监测到文件系统中发生的各种操作如文件打开,读写,关闭等,并将信息记录下来提供给用户查询,同时管理员用户可以控制文件安全管理功能的开启与关闭。对于系统运行信息的记录,Google提供了一个命令行工具Logcat,它能够以日志的形式将不同程序运行的过程记录下来。但简单的利用Logcat并不能满足文件管理器安全监控的目的。Logcat的设计目的主要用于程序的调试,相当有限的事件被导入到日志信息中,而关于文件I/O或进程管理的原始事件都没有得到保存。另外只有在程序中进行显式的调用时,Logcat才会把信息记录下来。

目前Linux平台下通常采用的对文件系统监控的技术主要是挂钩系统调用,即在用户态下挂钩open()、read()、write()等文件操作的系统调用过程来监控对文件访问的情况,但是这种方式有一些不足。(1)Linux 2.4.1 8版本后就不再导出系统调用表sys.call—table,虽然还可以通过读取/dev/kmem设备文件得到中断调用地址,来实现系统调用函数的劫持,但是这样做也给安全埋下隐患。(2)要想劫持系统调用,首先需要跳转到自定义的函数,然后再调用原来的系统函数,这种方法在多线程环境下并不健壮。
借鉴以往开发的不足,同时结合文件管理器的实际情况,在本文的文件监控功能开发过程中,采用了在内核空间中基于系统调用获取文件操作信息的方法。Android系统基于Linux 2.6内核,其底层同样支持虚拟文件系统(VFS)的机制。

  • VFS是位于具体文件系统之上的抽象层,所隐含的主要思想在于引入了一个通用文件模型,这个模型能够较好的表示所有Linux支持的文件系统。它主要由一组抽象的、标准的文件操作构成,这样就可以对上层用户程序隐藏各种不同的文件系统实现细节,为用户程序提供了一个虚拟的、统一的文件系统操作界面。当用户态的进程访问实际文件时,都会在VFS的抽象层建立对应的文件数据结构,通过结构中操作函数指针跳转到实际文件系统的对应执行过程中去。正是因为VFS的存在,使得上层应用和底层文件系统能够有效地协同工作,我们也正利用这一点,在VFS中对系统调用函数进行截获,从而得到各种不同的文件访问信息。把信息由内核空间传送给用户空间的任务可以由内核连接器来完成。

  • 连接器是Linux 2.6内核新引入的用于内核空间与用户空间通信的机制,与一般的netlink相比,它提供了更容易使用的接口。对用户态而言,连接器的使用与普通的netlink没有太大差别,只要指定netlink协议类型为NETLINK CONNECToR就可以了。但因为引用连接器函数库用c语言编写的用户态程序不被Dalvik虚拟机所支持,所以在应用中,我们在用户态单独放置与内核进行信息传递的程序,间接地来完成信息的接收工作。文件监控信息获取过程如图所示。

对于文件监控功能的打开与关闭控制,我们可以在内核文件监控连接器中设定一个控制开关,每次系统启动时都默认为关闭状态。再把用户态的消息接收程序设定为系统的守护进程,这样在正常情况下每次系统内核初始化完毕进入用户空间后,消息接收程序就会被引导运行,然后可以由它通过向内核连接器发送消息来控制连接器中开关的打开。控制开关打开后,连接器才会正常工作,把收到的文件访问信息发送到用户空间中。把用户空间中消息接收程序设为系统的守护进程,可以通过修改Android根文件系统中的init.rc文件来实现,在其中添加应用名称及在文件系统中的路径即可。利用这一点,我们可以在应用层代码中通过修改已知路径下该消息接收程序的名称来间接地达到功能控制的目的。当消息接收程序的名字被修改后,系统的对应守护进程设置无效,系统进入后消息接收程序并没有被引导启动,内核连接器因为没有收到打开开关的消息而继续处于停止工作状态,达到了关闭文件监测功能的目的。要指出的是,当Android模拟器运行之后,根目录、/system目录等即变为只读属性,为了实现应用层程序对消息接收程序的名称修改操作,我们只能把消息接收程序放置在系统的/data路径下。文件监控功能的控制过程示意图如图所示。

综上所述,文件管理器安全管理功能为系统应用层提供信息查询和功能控制的接口。在程序实现过程中,可以基于函数调用在Android内核VFS的文件I/O操作流程中,截获不同类型的文件访问信息,然后通过连接器消息发送函数进行消息的组装和传递,并最终由连接器API函数Cn netlink send发送给用户空间消息接收程序。这样系统中实时发生的文件访问操作就被记录了下来,用户也可以随时通过界面OptionsMenu菜单项读取特定的记录文件进行查询。用户对功能运行状态的改变可以通过在内核连接器中定义一个控制开关来实现。每次Android系统启动时,若新建的连接器回调函数接收到用户空间消息接收程序发送来的启动指令,则打开该功能控制开关,文件安全管理功能正常运行。否则开关一直处于默认的关闭状态。而启动指令的发送与否,跟消息接收程序能否成功设置为系统的守护进程密切相关,这一点可以通过修改ramdisk.img镜像中init.rc文件内容和特定路径下消息接收程序名称的方法来实现。我们需要在系统启动前对镜像文件修改完毕并在启动时予以加载,随后在文件管理器的参数设置界面,用户可以触发应用层对消息接收程序的名称修改过程,达到功能控制的目的。文件管理器的安全管理功能逻辑架构如图所示。

[项目代码托管](http://git.oschina.net/md2017/androidfilemanangentproject/tree/master/lib)