I am writing an application for which I need to intercept some filesystem system calls eg. unlink. I would like to save some file say abc. If user deletes the file then I need to copy it to some other place. So I need unlink to call my code before deleting abc so that I could save it. I have gone through threads related to intercepting system calls but methods like LD_PRELOAD it wont work in my case because I want this to be secure and implemented in kernel so this method wont be useful. inotify notifies after the event so I could not be able to save it. Could you suggest any such method. I would like to implement this in a kernel module instead of modifying kernel code itself. Another method as suggested by Graham Lee, I had thought of this method but it has some problems ,I need hardlink mirror of all the files it consumes no space but still could be problematic as I have to repeatedly mirror drive to keep my mirror up to date, also it won't work cross partition and on partition not supporting link so I want a solution through which I could attach hooks to the files/directories and then watch for changes instead of repeated scanning. I would also like to add support for write of modified file for which I cannot use hard links. I would like to intercept system calls by replacing system calls but I have not been able to find any method of doing that in linux > 3.0. Please suggest some method of doing that.
4 Answers
As far as hooking into the kernel and intercepting system calls go, this is something I do in a security module I wrote:
https://github.com/cormander/tpe-lkm
Look at hijacks.c and symbols.c for the code; how they're used is in the hijack_syscalls
function inside security.c. I haven't tried this on linux > 3.0 yet, but the same basic concept should still work.
It's a bit tricky, and you may have to write a good deal of kernel code to do the file copy before the unlink, but it's possible here.

- 7,239
- 1
- 39
- 43
-
Hello Thanks for your reply. I tried compiling it on system with linux 3.0.0.13 but it did not compile it gave some error `error: unknown field ‘ctl_name’` but It compiled on linux 2.6.32 I will try using it on that system and see if I could make use of it. – gaurav Dec 23 '11 at 09:17
-
The ctl_name is part of the sysctl configuration code, so it's not necessary for the hijack sections of the code to work. I'll eventually port the code to 3.x – Corey Henderson Dec 23 '11 at 15:45
-
That will be nice of you, could you give me some pointers regarding what approach you are using or I dive into the code to see that. If I get an idea I would port it. – gaurav Dec 24 '11 at 05:11
-
1I just posted an overview of how it works - http://cormander.com/2011/12/how-to-hook-into-hijack-linux-kernel-functions-via-lkm/ – Corey Henderson Dec 24 '11 at 06:28
-
Hello, Thanks a lot for the overview I have gone through it. Nicely written overview thanks a lot. You have done a total hack on the kernel. Have you inspired from kprobe code ? Can we skip the system call completely ? – gaurav Dec 26 '11 at 06:27
-
I was inspired by a project that was inspired by kprobes; KEDR. Yes, you can skip the call completely, simply dont call the orig kernel funtion from inside the hijack. Thats essentially how the TPE is implemented; is doesnt call the exec under certain conditions. – Corey Henderson Dec 26 '11 at 17:38
-
Oh I see. Nice project and idea indeed. Can we skip the system call in Kprobes ? I tried to compile the code on linux 3.x, I don't think ctl_name and strategy are part of struct ctl_table anymore and are thus giving errors. Do we need them or these initialization could be removed ? – gaurav Dec 29 '11 at 06:33
-
If you comment out all the ctl_table structs in sysctl.c, along with the code inside tpe_config_init() and tpe_config_exit(), it'll bybass the configuration entirely, and use the hard-coded defaults at the top of that file. – Corey Henderson Dec 29 '11 at 07:31
-
I commented that code entirely, ie. with nothing done in tpe_config_init the command to insert the module hanged and whole system hanged. Nothing could be done , I tried putting print to see what was going on but system just crashes and I have to hard reboot only. – gaurav Dec 29 '11 at 08:47
-
One more thing I wanted to ask is can we skip the system call in kprobes too ? – gaurav Dec 29 '11 at 08:48
-
What OS/version are you using, and are you using a custom kernel, or the distro kernel? I'll check it out. As far as kprobes go, I don't use them, was just inspired by them. I haven't tried to bypass kprobes since I don't use it. – Corey Henderson Dec 29 '11 at 15:23
-
I am using Ubuntu 11.10 with linux 3.0.0-14 . Its the distro kernel. Do I need to use a custom kernel ? I checked the config of distro kernel it has kallsyms method enabled. Still the system just freezes as I use the insmod command. – gaurav Dec 30 '11 at 07:36
-
I had a look at the 3.0.0 kernel's functions - at least one that I hijack has a change in the number of function arguments. This is likely the problem. Next I get a chance, I'll check this out. See my profile for my email address. – Corey Henderson Dec 30 '11 at 15:50
-
I think if there was any function parameter mismatch compilation should give an error, but it got compiled successfully. – gaurav Dec 31 '11 at 09:58
-
It doesn't work the way you think. It doesn't expect the external functions at compile time. Email: corman /AT/ cormander /DOT/ com – Corey Henderson Dec 31 '11 at 17:55
-
Oh I see, you are manipulating functions using pointers and symbols so a wrong manipulation could fail the system. Thanks I will mail you now on. – gaurav Jan 01 '12 at 06:57
One suggestion could be Filesystems in Userspace (FUSE.) That is, write a FUSE module (which is, granted, in userspace) which intercepts filesystem-related syscalls, performs whatever tasks you want, and possibly calls the "default" syscall afterwards.
You could then mount certain directories with your FUSE filesystem and, for most of your cases, it seems like the default syscall behavior would not need to be overridden.

- 18,726
- 23
- 95
- 134
-
1Thanks for your answer , can I mount / using FUSE filesystem. Would I need to replace all the filesystem calls individually as I think VFS will call my FUSE filesystem it would need to come in between say VFS and ext4. Am I right ? – gaurav Dec 21 '11 at 17:30
You can watch unlink events with inotify, though this might happen too late for your purposes (I don't know because I don't know your purposes, and you should experiment to find out). The in-kernel alternatives based on LSM (by which I mean SMACK, TOMOYO and friends) are really for Mandatory Access Control so may not be suitable for your purposes.
If you want to handle deletions only, you could keep a "shadow" directory of hardlinks (created via link
) to the files being watched (via inotify
, as suggested by Graham Lee).
If the original is now unlinked, you still have the shadow file to handle as you want to, without using a kernel module.

- 35,395
- 6
- 71
- 104
-
-
Is it possible for you to change your mount points? if so, It may be possible to write a FUSE filesystem. You may want to have a look at [collectfs](http://code.google.com/p/collectfs/) which might do what you want. – Hasturkun Dec 21 '11 at 17:22
-
No I won't be able to change mount points every time like if I want to work on "/" this won't be possible. I will see collectfs. – gaurav Dec 21 '11 at 17:33
-
If you can mount at all, you could make the application run in a `chroot` jail, have your FUSE fs mirror `/`, It's probably still easier to do than to implement a kernel module. – Hasturkun Dec 21 '11 at 17:51
-
I think this could work for me, would I be able to intercept open/ link system call too. Would I need to replace all the filesystem calls individually as I think VFS will call my FUSE filesystem it would need to come in between say VFS and ext4. Am I right ? Also if I mount / ie. the root partition I won't be able to see removable drives and updated changes. Would I ? – gaurav Dec 22 '11 at 03:57