By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,412 Members | 1,006 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Writing System Call Wrappers in User Space.

ashitpro
Expert 100+
P: 542
Writing System Call Wrappers in User Space.

Recently I saw a post in Linux/Unix section to know the user who deleted the file in linux. Currently there is nothing in linux which could achieve this. There are certain tools which profiles the activities on file system, but none of these provides the particular user information. Main task for all these tools to check the performance of the system.
First I thought why not to hook the unlink system call and log the users who are deleting the files. This was supposed to be done inside kernel mode.
There are certain limitations for hooking the system calls inside kernel.
1. System call table is not exportable in 2.6 kernel.
2. Logging the user who deleted the file is simple task so can be done using kernel module. Nobody should expect to write the new system call in kernel, or anything else which would end up with kernel compilation.
3. Even if somebody manage to develop a kernel module which would log the user, it would be very difficult to manage the portability and compatibility of the code with all versions of the kernel.

So, why not to write something in user mode to achieve this task. With this method you can write a wrapper around any system call in user space.

Unlink is the system call which ultimately deletes the file from file system.
So here we’ll try to write a wrapper over it for just an example.
The approach is very simple. We first write our own unlink function which will perform the necessary logging task and at last it will call the original unlink function.
We can get the address of the original unlink system call from libc.so (not sure) by dlsym() function. We’ll compile our code and build the share object file.
The important task is to load out library before the original library, this will make sure that out unlink function get call. We can achieve this by setting environmental variable called LD_PRELOAD to our library.

Let’s do some coding…
Expand|Select|Wrap|Line Numbers
  1. //wrapper.c
  2. #include <dlfcn.h>
  3. #include <stdio.h>
  4.  
  5. int unlink(const char * path) //original signature of the unlink system call.
  6. {
  7.     //you can perform any task here..
  8. printf("\nDon’t get lost in processing….\n");
  9. typedef int (*FP_unlink)(const char*);
  10. FP_unlink org_unlink = dlsym(((void *) -1l), "unlink");
  11. return org_unlink(path);
  12. }
  13.  


Compile this file as:
gcc -fPIC -c -Wall wrapper.c -o wrapper.o
gcc -shared wrapper.o -ldl -lstdc++ -o wrapper.so

Now, we’ll set the LD_PRELOAD variable. We can achieve this either by writing any shell script, or direct export command at shell.

export LD_PRELOAD=$LD_PRELOAD:./wrapper.so

To test this wrapper, just create any file and try to delete it with rm command..

$>echo “hi” > hello.txt
$>rm –rf hello.txt

Don’t get lost in processing….
$>
Nov 11 '08 #1
Share this Article
Share on Google+