Re: overloading system calls.

Andi Kleen (ak@muc.de)
31 May 1998 19:55:26 +0200


Tigran Aivazian <tigran@aivazian.demon.co.uk> writes:

> Hello guys,
>
> Is there a way to replace a system call dynamically within a module?
> Naive approach of putting something like:
>
> asmlinkage int sys_getpid(void)
> {
> printk(KERN_INFO "my getpid() for <%s>\n", current->comm);
> return current->pid;
> }

You have two ways:

a) patch the table in arch/i386/kernel/entry.S at module load time.
This is rather ugly. The pointer is an ordinary function pointer so you
could insert your code there.

b) The better way: use LD_PRELOAD for the program you want to patch:

mygetpid.c

#include <dlfcn.h>
int getpid()
{
static int (*real_getpid)(int);

write(2, "my getpid!\n", 11);
if (!real_getpid) {
real_getpid = dlsym(RTLD_NEXT, "getpid");
if (!real_getpid)
return -1;
}
return real_getpid();
}

Compile with:

gcc -shared mygetpid.c -o mygetpid.so -ldl

LD_PRELOAD=./mygetpid.so program_to_patch

Note that this doesn't work when the program is setuid and you're not root.
Also it is not possible to catch calls from libc because those are already
prelinked (e.g. when you want to patch write() printf() won't be intercepted).
If you want that you can patch libc and use LD_LIBRARY_PATH to link with your
new libc.

-A.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu