468,556 Members | 2,237 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Share your developer knowledge by writing an article on Bytes.

Writing System Call Wrappers in User Space.

542 Expert 512MB
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>
  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. }

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
0 10403

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

5 posts views Thread by Michelle A. | last post: by
16 posts views Thread by iwdu15 | last post: by
8 posts views Thread by songstre | last post: by
8 posts views Thread by Henrik | last post: by
2 posts views Thread by MAx | last post: by
1 post views Thread by sophia.agnes | last post: by
30 posts views Thread by Cramer | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by UniDue | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.