intercepting file system system calls
Asked Answered
A

4

10

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.

Avogadro answered 21/12, 2011 at 10:31 Comment(0)
U
7

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.

Uela answered 22/12, 2011 at 17:11 Comment(16)
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.Avogadro
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.xUela
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.Avogadro
I just posted an overview of how it works - cormander.com/2011/12/…Uela
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 ?Avogadro
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.Uela
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 ?Avogadro
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.Uela
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.Avogadro
One more thing I wanted to ask is can we skip the system call in kprobes too ?Avogadro
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.Uela
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.Avogadro
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.Uela
I think if there was any function parameter mismatch compilation should give an error, but it got compiled successfully.Avogadro
It doesn't work the way you think. It doesn't expect the external functions at compile time. Email: corman /AT/ cormander /DOT/ comUela
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.Avogadro
M
3

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.

Manducate answered 21/12, 2011 at 17:14 Comment(1)
Thanks 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 ?Avogadro
K
2

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.

Kishke answered 21/12, 2011 at 11:25 Comment(0)
M
1

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.

Mccool answered 21/12, 2011 at 13:12 Comment(5)
I have edited the question , Please could you suggest something now.Avogadro
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 which might do what you want.Mccool
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.Avogadro
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.Mccool
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 ?Avogadro

© 2022 - 2024 — McMap. All rights reserved.