I have replaced the execve() kernel API with my own implementation but it
doesn't work well.
extern void * sys_call_table[]
asmlinkage int (*system_execve)(const char *, const char **, const char
**);
asmlinkage int my_execve(const char * filename, const char **argv, const
char **envp)
{
return system_execve(filename, argv, envp);
}
int init_module()
{
system_execve = sys_call_table[__NR_execve];
sys_call_table[__NR_execve] = my_execve;
}
void cleanup_module()
{
sys_call_table[__NR_execve] = system_execve;
}
Does anybody know where is the problem?
Thanks in advance.
-Abel.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
"it doesn't work well" is a bit vague...
I am guessing that you are getting an unresolved symbol. Modifying the
system call table is not and probably never will be available for
modules. The syscall table is very architecture dependant, and is not
exported to modules.
--
Brian Gerst
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"=
> Hi everybody,
>
> I have replaced the execve() kernel API with my own implementation b=
ut it
> doesn't work well.
>
> extern void * sys_call_table[]
>
> asmlinkage int (*system_execve)(const char *, const char **, const =
char
> **);
>
This is not the prototype of sys_execve(). It looks like this :
asmlinkage int sys_execve(struct pt_regs regs)
this syscall is a little more tricky to track than the others, because =
the
pt_regs is not a pointer here. That means you can't just stick in a cal=
l
inbetween like with most syscalls.
Instead you should just copy the code from sys_execve() and call do_exe=
cve
directly from the module (it is exported, so you can).
but - you will need to do this for all architectures as they differ
and are you really sure you need to do this ?
john
> "it doesn't work well" is a bit vague...
>
> I am guessing that you are getting an unresolved symbol. Modifying the
> system call table is not and probably never will be available for
> modules. The syscall table is very architecture dependant, and is not
> exported to modules.
This isn't true, you can replace syscalls fine in modules on x86. I can't
comment on other architectures. It's rarely a good idea though of course.
You might want to check out the "overloader" module at
http://bdolez.free.fr/
john
p.s. abel, your module exit has a horrendous race with module unload, and
processes sleeping in the system call ...
--
"The Internet is a shallow and unreliable electronic repository of dirty pictures, inaccurate rumors,
bad spelling and worse grammar, inhabited largely by people with no demonstrable social skills."
- Chronicle of Higher Education
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Even your overloader has a small module unload race. The only 100%
race-free way is to put module usage counting into the core kernel, like
the VFS changes with ->open that were done in 2.3.x. This would mean
added overhead for all syscalls, so many people would oppose this.
--
Brian Gerst
> Even your overloader has a small module unload race. The only 100%
> race-free way is to put module usage counting into the core kernel, like
> the VFS changes with ->open that were done in 2.3.x. This would mean
> added overhead for all syscalls, so many people would oppose this.
>
> --
Whose overloader ? I didn't write it ...
anyway, you can just put refcounts in your hijacked system calls; that is
the safe way to do it, and doesn't require any kernel patches, just extra
cost in the intercepted system calls.
e.g. :
my_syswhatever(...)
{
MOD_INC_USE_COUNT;
original_syswhatever(...);
MOD_DEC_USE_COUNT;
}
Can you explain to me the race with this approach ?
thanks
john
--
"The Internet is a shallow and unreliable electronic repository of dirty pictures, inaccurate rumors,
bad spelling and worse grammar, inhabited largely by people with no demonstrable social skills."
- Chronicle of Higher Education
-
I have rewritten my function and it seems that it works well.
Remember; it is only an example:
=========================
=========================
=========================
=
extern void *sys_call_table[];
asmlinkage int (*system_execve)(struct pt_regs);
asmlinkage int (*system_kill)(pid_t, int);
asmlinkage void (*system_exit)(int);
asmlinkage int my_kill(pid_t pid, int sign)
{
printk("\nPROCMON: Killing process %d.\n", pid);
return system_kill(pid, sign);
}
asmlinkage void my_exit(int status)
{
printk("\nPROCMON: Exiting process %d.\n", current->pid);
return system_exit(status);
}
asmlinkage int my_execve(struct pt_regs regs)
{
int error;
char * filename;
lock_kernel();
filename = getname((char *) regs.ebx); //What does getname() do?
error = PTR_ERR(filename);
if (IS_ERR(filename))
{
unlock_kernel();
return error;
}
error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, =
®s);
if (error == 0)
{
current->flags &= ~PF_DTRACE; // ?????
printk("\nPROCMON: Executing process (%d) %s\n", current->pid, filena=
me);
}
putname(filename); //What does putname() do?
unlock_kernel();
return error;
}
int init_module()
{
system_execve = sys_call_table[__NR_execve];
system_kill = sys_call_table[__NR_kill];
system_exit = sys_call_table[__NR_exit];
sys_call_table[__NR_execve] = my_execve;
sys_call_table[__NR_kill] = my_kill;
sys_call_table[__NR_exit] = my_exit;
return 0;
}
void cleanup_module()
{
if (sys_call_table[__NR_execve] != my_execve)
{
printk(KERN_INFO "\nThe system has been left in a unpredictable
state.\nPlease, reboot it.\n");
}
sys_call_table[__NR_exit] = system_exit;
sys_call_table[__NR_kill] = system_kill;
sys_call_table[__NR_execve] = system_execve;
}
If you know a better way, please say me.
-Abel.
-----Original Message-----
From: John Levon [mailto:m...@compsoc.man.ac.uk]
Sent: miércoles, 04 de octubre de 2000 16:21
To: Abel Muñoz Alcaraz
Subject: RE: execve replacement.
On Wed, 4 Oct 2000, [iso-8859-1] Abel Muñoz Alcaraz wrote:
> I need to create a processes hook.
> Do you know an other way?
>
> -Abel.
what do you mean by a hook ? what exact info do you need and when ? tha=
n
john
--
"The Internet is a shallow and unreliable electronic repository of dirt=
y
pictures, inaccurate rumors,
bad spelling and worse grammar, inhabited largely by people with no
demonstrable social skills."
- Chronicle of Higher Education
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"=
There is a small period of time between the last MOD_DEC_USE_COUNT and
the return of the function where the module could be unloaded by another
CPU (SMP only). It is a tiny race window, but still possible.
MOD_DEC_USE_COUNT is only safe if it does not reduce the use count to
zero. The only exceptions to this are if the caller to the module takes
the Big Kernel Lock or unload_lock. This race was brought to light
because lock_kernel() was removed from the open path in the VFS. Any
time you call through a function pointer that could possibly be in an
unreferenced module, you need to use try_inc_mod_count() before calling.
--
Brian Gerst
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> I need that somebody says to my module when a user application has st=
arted
> or finished, and what is its name and pid.
>
you do not need to trace system calls then. Provide a misc char device,
and get the user app to open it. Then you can trace its existence via t=
he
open/close routines.
john
--
"The Internet is a shallow and unreliable electronic repository of dirt=
y pictures, inaccurate rumors,
bad spelling and worse grammar, inhabited largely by people with no de=
monstrable social skills."
- Chronicle of Higher Education
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"=
> John Levon wrote:
> > anyway, you can just put refcounts in your hijacked system calls; that is
> > the safe way to do it, and doesn't require any kernel patches, just extra
> > cost in the intercepted system calls.
> >
> > e.g. :
> >
> > my_syswhatever(...)
> > {
> > MOD_INC_USE_COUNT;
> > original_syswhatever(...);
> > MOD_DEC_USE_COUNT;
> > }
> >
> > Can you explain to me the race with this approach ?
>
> There is a small period of time between the last MOD_DEC_USE_COUNT and
> the return of the function where the module could be unloaded by another
> CPU (SMP only). It is a tiny race window, but still possible.
>
Wouldn't this require another module to be loaded inbetween the
MOD_DEC_USE_COUNT, and the function exit, to actually be dangerous ?
I don't know ...
john
--
"The Internet is a shallow and unreliable electronic repository of dirty pictures, inaccurate rumors,
bad spelling and worse grammar, inhabited largely by people with no demonstrable social skills."
- Chronicle of Higher Education
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
1. John Levon already told you that if the syscalls sleep and your modu=
le
is unloaded then they will return nowhere. Just put MOD_INC_USE_COUNT a=
nd
MOD_DEC_USE_COUNT in my_kill/my_exit/my_execve as he suggested.
2. your module won't work on mips architecture but you probably know th=
is
(or don't care)
3. getname allocates a "name object" from names_cachep SLAB cache and
copies a filename from userspace into it. putname frees this object
4. just trapping when processes do exit(2) system call may not be enoug=
h
-- depends on what you want to achieve. For example, a process may be
"forced to exit" if he/she invokes a bdflush(2) system call, see
sys_bdflush() in fs/buffer.c. So you may need a hook in do_exit() (see
kernel/exit.c).
Regards,
Tigran
On Wed, 4
Oct 2000, Abel Muńoz Alcaraz wrote:
> I need that somebody says to my module when a user application has st=
arted
> or finished, and what is its name and pid.
>
> error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx=
, ®s);
> if (error == 0)
> {
> current->flags &= ~PF_DTRACE; // ?????
>
> printk("\nPROCMON: Executing process (%d) %s\n", current->pid, file=
name);
> On Wed, 4 Oct 2000, [iso-8859-1] Abel Muńoz Alcaraz wrote:
>
> > I need to create a processes hook.
> > Do you know an other way?
> >
> > -Abel.
>
> what do you mean by a hook ? what exact info do you need and when ? t=
han
>
> john
>
> --
> "The Internet is a shallow and unreliable electronic repository of di=
rty
> pictures, inaccurate rumors,
> bad spelling and worse grammar, inhabited largely by people with no
> demonstrable social skills."
> - Chronicle of Higher Education
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kerne=
l" in
> the body of a message to majo...@vger.kernel.org
> Please read the FAQ at http://www.tux.org/lkml/
>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"=