拦截文件系统系统调用

10

我正在编写一个应用程序,需要拦截一些文件系统系统调用,例如unlink。我想保存一些文件,比如abc。如果用户删除了该文件,那么我需要将其复制到其他地方。因此,在删除abc之前,我需要unlink调用我的代码,以便我可以保存它。我已经研究过与拦截系统调用相关的线程,但是像LD_PRELOAD这样的方法在我的情况下无法工作,因为我希望这是安全的,并且在内核中实现,所以这种方法是无用的。inotify会在事件发生后通知我,所以我不能能够保存它。你能否建议任何这样的方法。我想在内核模块中实现这个功能,而不是修改内核代码本身。 Graham Lee建议的另一种方法,我已经考虑过这种方法,但它有一些问题,我需要所有文件的硬链接镜像,它不会占用空间,但仍然可能存在问题,因为我必须反复镜像驱动器以保持我的镜像最新,而且它不能在不支持链接的分区上跨分区工作,因此我希望通过将钩子附加到文件/目录上,然后监视更改而不是重复扫描来找到解决方案。 我还想添加对修改后文件的写入支持,但我不能使用硬链接。 我想通过替换系统调用来拦截系统调用,但是我还没有找到在Linux > 3.0中执行该操作的方法。请建议一些方法。

4个回答

7
就挂钩内核和拦截系统调用而言,这是我在一个安全模块中所做的事情:

https://github.com/cormander/tpe-lkm

请查看 hijacks.c 和 symbols.c 的代码;它们的使用方法在 security.c 中的 hijack_syscalls 函数中。我尚未在 Linux > 3.0 上尝试过这种方法,但是相同的基本概念仍然适用。
这有点棘手,您可能需要编写大量内核代码来在取消链接之前进行文件复制,但在这里是可行的。

你好,谢谢回复。我尝试在Linux 3.0.0.13系统上编译它,但无法编译,出现了一些错误“error: unknown field ‘ctl_name’”,但是在Linux 2.6.32上编译成功。我将尝试在那个系统上使用它,并看看能否利用它。 - gaurav
如果您能给我一些指针,告诉我您使用的方法,那就太好了,否则我将深入代码进行研究。如果我有想法,我会进行移植。 - gaurav
1
我刚刚发布了一个关于它如何工作的概述 - http://cormander.com/2011/12/how-to-hook-into-hijack-linux-kernel-functions-via-lkm/ - Corey Henderson
你好,非常感谢你的概述,我已经仔细阅读了它。概述写得很好,非常感谢。你对内核进行了完全的黑客攻击,你是从Kprobe代码中获得灵感的吗?我们能否完全跳过系统调用? - gaurav
哦,我明白了。这个项目和想法确实不错。我们能否在Kprobes中跳过系统调用?我尝试在Linux 3.x上编译代码,我认为ctl_name和strategy不再是struct ctl_table的一部分,因此会出现错误。我们需要它们吗?还是可以将这些初始化删除? - gaurav
显示剩余11条评论

3
一个建议是使用Userspace文件系统(FUSE)。也就是说,编写一个FUSE模块(虽然在用户空间),拦截与文件系统相关的系统调用,执行您想要的任何任务,并在可能之后调用“默认”系统调用。您随后可以使用您的FUSE文件系统挂载某些目录,在大多数情况下,似乎不需要覆盖默认系统调用行为。

1
谢谢您的回答,我能否使用FUSE文件系统挂载/?我需要逐个替换所有文件系统调用吗?我认为VFS会调用我的FUSE文件系统,因此它需要介于VFS和ext4之间。我是对的吗? - gaurav

2
你可以使用inotify来监视取消链接事件,但这可能对你的目的来说有些晚了(我不知道因为我不知道你的目的,你应该进行实验以找出)。基于LSM的内核替代方案(我指SMACK、TOMOYO等)真正适用于强制访问控制,因此可能不适合你的目的。

1

如果你只想处理删除操作,你可以保留一个“影子”目录的硬链接(通过link创建)到被监视的文件(通过inotify,正如Graham Lee所建议的那样)。

如果原始文件现在已取消链接,则您仍然可以使用影子文件进行处理,而不必使用内核模块。


我已经编辑了问题,请您现在能否提出一些建议。 - gaurav
你能改变挂载点吗?如果可以,可能可以编写FUSE文件系统。你可能需要查看collectfs,它可能做你想要的事情。 - Hasturkun
不,我不能每次更改挂载点,比如如果我想在“/”上工作,这是不可能的。我会考虑使用collectfs。 - gaurav
如果您能够挂载,您可以将应用程序运行在 chroot 监狱中,并让您的 FUSE 文件系统镜像 /。这可能仍然比实现内核模块更容易。 - Hasturkun
我认为这对我可能有用,我能拦截打开/链接系统调用吗?我需要单独替换所有文件系统调用吗?因为我认为VFS会调用我的FUSE文件系统,所以它需要在VFS和ext4之间插入。我是对的吗?另外,如果我挂载/即根分区,我将无法看到可移动驱动器和更新的更改。是吗? - gaurav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接