7

I want to do something before writing data into hard disk. I don't known any solutions. To avoid editing kernel source code, is there any locations that I can use hook function as a loadable module?

UPDATE: Thanks all, LSM is good for API hooks. But I want to find other solution that provides mechanism hook read/write block of data. It can avoid re-encrypting all file after updating file.

I think there is something that I can modify between filesystem (ext2, ext3,...) and buffer cache.

thanhtv
  • 323
  • 1
  • 4
  • 12

5 Answers5

2

Use Linux Security Modules. These are loadable kernel modules, that provide hooks to mediate access to various internal objects in the kernel. You can use the hook to filesystem, or inodes as per your requirement. A good place to start is to read Greg Kroah Hartman's paper on LSM. Then you can visit this link, where it is shown along with an example how to make use of LSM hooks. The example is to mediate access to the system only when a particular USB is inserted, and is a good reference point on how to start with LSM hooks.

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Varun
  • 187
  • 1
  • 6
  • Thanks, I am writing a small example but get problem with `register_secutiry (Unknown symbol register_security (err 0))` Is LSM is a loadable module? I read some comments, they said that the hook module need compile with kernel. It means hook module is not loadable. – thanhtv Apr 03 '13 at 08:38
  • You can't use `register_security` with modern kernels as LSM can't be loaded as a module in a common way. See that link for details: http://stackoverflow.com/questions/10428212/how-can-i-implement-my-own-hook-function-with-lsm/10431534#10431534 – Ilya Matveychikov Apr 03 '13 at 10:38
  • Yeah, Ilya is right. register_security doesn't work since 2.6.24. The link(the one with the USB example) I asked you to go through, mentions this. You'll have to make a module for yourself[this means editing Linux's source, makefiles etc.] and compile the kernel with it. I suggest you do what the author of the article has done follow each step, you'll get a clearer understanding. The main part will be finding the place where the pages are written to the disk, I'll see if I can dig around in the code a little. – Varun Apr 04 '13 at 15:47
  • How deep can I hook to read/write operations? I only can encrypt data if i can hook to read/write block of bytes. If read/write whole file, it is time consuming! – thanhtv Apr 05 '13 at 04:19
  • @Varun: The point was that you can have LSM outside the kernel. You can easily find `security_ops` pointer using d'asm, for example. – Ilya Matveychikov Apr 11 '13 at 13:46
2

Well, it's interesting question.

Unfortunately, even LSM doesn't help here. As a possible solution I'll recommend use address_space_operations tables and hook writepage function. For example, look at 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 };

So, in case of ext3 filesystem we need to find this struct in memory and replace the writepage pointer to point to our_writepage wrapper. Note also that this table is in read-only memory and you need to handle it correctly.

EDIT:

With LSM it is possible to hook on inode open operation and replace inode->i_mapping->a_ops inplace.

Ilya Matveychikov
  • 3,936
  • 2
  • 27
  • 42
1

Try the FUSE(https://github.com/libfuse/libfuse).

This is a file system in userspace. You can write file I/O handler in user space and simply mount it as execution of application.

Jafffy
  • 115
  • 8
1

This sample example demonstrates how to hack libc functions, such as open\close\read\write, etc.

You could make a dynamic lib file your_write_lib.so , which implements a new write function.

/* 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));
}

compile your_write_lib.c into .so file:

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

Then run your Application like this:

LD_PRELOAD=./your_write_lib.so your_application

With the help of LD_PRELOAD=./your_write_lib.so, the Linux OS will load your_write_lib.so first, then the glibc. The new open will hide the origin open function of glibc to your Application. You CAN do anything in the new open function, such as "do something before writing".

  • You appear to be the owner of the GitHub repository that you linked to. While it's fine to include links to your own repository, you need to include a disclaimer noting your own affiliation. Please see: https://stackoverflow.com/help/promotion. Please [edit] your answer. – Cody Gray - on strike Nov 05 '21 at 13:02
-3

I don't think this is possible. When userspace invokes a file I/O the file system implementation or the generic implementation will be called from VFS. what you would need is to change this function pointers to point to your module, which encrypts your data and then invokes the file system function.

I did something like this in university, but it was an old kernel and you had to set a specific configuration flag. If I remember this flag has disappeared as you don't want kernel modules to mess around with functions pointers outside their scope.

In any case, you can find the module here: https://motzblog.wordpress.com/2007/10/27/linux-monitoring-module/

But be warned, it was a university project, so the code quality isn't what you except from Linux kernel code.

matthias.bgg
  • 165
  • 4