tags:

views:

1991

answers:

10

Hello !

Besides the LD_PRELOAD trick , and Linux Kernel Modules that replace a certain syscall with one provided by you , is there any possibility to intercept a syscall ( open for example ) , so that it first goes through your function , before it reaches the actual open ?

+3  A: 

Why can't you / don't want to use the LD_PRELOAD trick?

Example code here:

/*
 * File: soft_atimes.c
 * Author: D.J. Capelis
 *
 * Compile:
 * gcc -fPIC -c -o soft_atimes.o soft_atimes.c
 * gcc -shared -o soft_atimes.so soft_atimes.o -ldl
 *
 * Use:
 * LD_PRELOAD="./soft_atimes.so" command
 *
 * Copyright 2007 Regents of the University of California
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char * pathname, int flags, ...);
int (*_open64)(const char * pathname, int flags, ...);

int open(const char * pathname, int flags, mode_t mode)
{
    _open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
    if(flags & O_CREAT)
        return _open(pathname, flags | O_NOATIME, mode);
    else
        return _open(pathname, flags | O_NOATIME, 0);
}

int open64(const char * pathname, int flags, mode_t mode)
{
    _open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
    if(flags & O_CREAT)
        return _open64(pathname, flags | O_NOATIME, mode);
    else
        return _open64(pathname, flags | O_NOATIME, 0);
}

From what I understand... it is pretty much the LD_PRELOAD trick or a kernel module. There's not a whole lot of middle ground unless you want to run it under an emulator which can trap out to your function or do code re-writing on the actual binary to trap out to your function.

Assuming you can't modify the program and can't (or don't want to) modify the kernel, the LD_PRELOAD approach is the best one, assuming your application is fairly standard and isn't actually one that's maliciously trying to get past your interception. (In which case you will need one of the other techniques.)

D.J. Capelis
A: 

I was looking for a global solution , and by global I want to be able to log all the calls that are made to open , specifically the filenames that are opened . I would have liked to use a LKM , but I don't really know how to "hijack" a function using it ( on a OpenSuse 11.0 , with a 2.6.x kernel ) . If anyone knows the solution using a LKM that would be helpfull. Thanks !

Vhaerun
Easy, but I'm late I know.http://sourceware.org/systemtap/examples/general/para-callgraph-verbose.stp stap para-callgraph-verbose.stp 'kernel.function("*@fs/ext3/*.c")' \'kernel.function("ext3_file_open") -c yourprogramhereIt'll show the matched funtion (which in this case should be one). I havn't tested it on openSuse, but this should be enough to get you started.
Wade Mealing
A: 

if you really need a solution you might be interested in the DR rootkit that accomplishes just this, http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 the article about it is here http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

sztanpet
Why suggest an obscure method when other, far more conventional alternatives exist? LD_PRELOAD being the most common.
Arafangion
because he wasnt looking for the more conventional ones, or at least thats what I gathered from his original question
sztanpet
+2  A: 

I don't have the syntax to do this gracefully with an LKM offhand, but this article provides a good overview of what you'd need to do: http://www.linuxjournal.com/article/4378

You could also just patch the sys_open function. It starts on line 1084 of file/open.c as of linux-2.6.26.

You might also see if you can't use inotify, systemtap or SELinux to do all this logging for you without you having to build a new system.

D.J. Capelis
A: 

Thank you guys ! You gave me enough information to keep going .

Vhaerun
+4  A: 

Valgrind can be used to intercept any function call. If you need to intercept a system call in your finished product then this will be no use. However, if you are try to intercept during development then it can be very useful. I have frequently used this technique to intercept hashing functions so that I can control the returned hash for testing purposes.

In case you are not aware, Valgrind is mainly used for finding memory leaks and other memory related errors. But the underlying technology is basically an x86 emulator. It emulates your program and intercepts calls to malloc/free etc. The good thing is, you do not need to recompile to use it.

Valgrind has a feature that they term Function Wrapping, which is used to control the interception of functions. See section 3.2 of the Valgrind manual for details. You can setup function wrapping for any function you like. Once the call is intercepted the alternative function that you provide is then invoked.

+3  A: 

If you just want to watch what's opened, you want to look at the ptrace() function, or the source code of the commandline strace utility. If you actually want to intercept the call, to maybe make it do something else, I think the options you listed - LD_PRELOAD or a kernel module - are your only options.

pjz
+1  A: 

If you just want to do it for debugging purposes look into strace, which is built in top of the ptrace(2) system call which allows you to hook up code when a system call is done. See the PTRACE_SYSCALL part of the man page.

Johan Dahlin
+2  A: 

Some applications can trick strace/ptrace not to run, so the only real option I've had is using systemtap

Systemtap can intercept a bunch of system calls if need be due to its wild card matching. Systemtap is not C, but a separate language. In basic mode, the systemtap should prevent you from doing stupid things, but it also can run in "expert mode" that falls back to allowing a developer to use C if that is required.

It does not require you to patch your kernel (Or at least shouldn't), and once a module has been compiled, you can copy it from a test/development box and insert it (via insmod) on a production system.

I have yet to find a linux application that has found a way to work around/avoid getting caught by systemtap.

Wade Mealing
A: 

I intercepted system call via LKM method successfully on Linux kernel version 2.6.24, so if you also want to how, please let me know : [email protected]