Linux文件系统的钩子函数

aij0ehis  于 2023-02-21  发布在  Linux
关注(0)|答案(5)|浏览(248)

我想在写数据到硬盘之前做一些事情。我不知道任何解决方案。为了避免编辑内核源代码,有没有什么地方可以使用钩子函数作为可加载模块?
更新:谢谢大家,LSM是很好的API挂钩。但我想找到其他解决方案,提供机制挂钩读/写块的数据。它可以避免重新加密所有文件后,更新文件。
我认为可以在文件系统(ext 2、ext 3...)和缓冲区缓存之间进行修改。

sqxo8psd

sqxo8psd1#

嗯,这是个有趣的问题。
不幸的是,即使是LSM也没有帮助,作为一个可能的解决方案,我推荐使用address_space_operations表和hook writepage函数,例如,看看ext3_writeback_aops:

1984 static const struct address_space_operations ext3_writeback_aops = {
1985         .readpage               = ext3_readpage,
1986         .readpages              = ext3_readpages,
1987         .writepage              = ext3_writeback_writepage,
1988         .write_begin            = ext3_write_begin,
1989         .write_end              = ext3_writeback_write_end,
1990         .bmap                   = ext3_bmap,
1991         .invalidatepage         = ext3_invalidatepage,
1992         .releasepage            = ext3_releasepage,
1993         .direct_IO              = ext3_direct_IO,
1994         .migratepage            = buffer_migrate_page,
1995         .is_partially_uptodate  = block_is_partially_uptodate,
1996         .error_remove_page      = generic_error_remove_page,
1997 };

因此,对于ext3文件系统,我们需要在内存中找到这个结构体,并替换writepage指针,使其指向our_writepage Package 器。还要注意,这个表位于只读内存中,您需要正确处理它。
编辑:
使用LSM,可以挂接inode打开操作并将inode->i_mapping->a_ops替换到位。

1hdlvixo

1hdlvixo2#

使用Linux Security Modules。这些是可加载的内核模块,提供钩子来协调对内核中各种内部对象的访问。您可以根据需要使用文件系统或inode的钩子。一个很好的起点是阅读Greg Kroah Hartman的paper on LSM。然后您可以访问link,其中展示了如何使用LSM钩子的示例。该示例是仅在插入特定USB时才调解对系统的访问,并且是如何开始使用LSM钩子的很好参考点。

c9qzyr3d

c9qzyr3d3#

这个示例演示了如何破解libc函数,例如open\close\read\write等。
您可以创建一个动态库文件 your_write_lib.so,它实现了一个新的 write 函数。

/* your_write_lib.c */

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <stdarg.h>

ssize_t write (int fd, const void * buf, size_t count){
    ssize_t (*glibc_write)(int fd, const void * buf, size_t count);

    glibc_write = dlsym(RTLD_NEXT, "write");

    // do whatever you want

    return glibc_write(fd, buffer, strlen(buffer));
}

your_write_lib.c 编译为 .so 文件:

gcc -Wall -fPIC -shared -o your_write_lib.so your_write_lib.c  -ldl

然后按如下方式运行应用程序:

LD_PRELOAD=./your_write_lib.so your_application

LD_PRELOAD=./your_write_lib.so 的帮助下,Linux操作系统将首先加载 your_write_lib.so,然后加载 glibc。新的 open 将对您的应用程序隐藏glibc的原始 open 函数。您可以在新的 open 函数中执行任何操作,例如“在写入之前执行某些操作”。

fzsnzjdm

fzsnzjdm4#

尝试使用保险丝https://github.com/libfuse/libfuse)。
这是一个用户空间的文件系统。你可以在用户空间编写文件I/O处理程序,并简单地将其挂载为应用程序的执行。

vh0rcniy

vh0rcniy5#

我认为这是不可能的。当用户空间调用一个文件I/O时,文件系统实现或泛型实现将从VFS调用。您需要做的是将此函数指针更改为指向您的模块,该模块将加密您的数据,然后调用文件系统函数。
我在大学里做过类似的事情,但那是一个老内核,你必须设置一个特定的配置标志。如果我记得这个标志已经消失了,因为你不想让内核模块在它们的作用域之外乱用函数指针。
在任何情况下,您都可以在这里找到该模块:https://motzblog.wordpress.com/2007/10/27/linux-monitoring-module/
但是要注意,这是一个大学项目,所以代码质量不是Linux内核代码所能达到的。

相关问题