Reputation: 11
I want to set a jprobe hook on do_execve to catch every executed program.
My code is working on <= 3.2 linux kernel (debian). This is my output on linux kernel 3.2:
[ 628.534037] registered: do_execve, ret: 0
[ 723.995797] execve: /usr/bin/vi
[ 726.807025] execve: /bin/dmesg
on 4.1 kernel I the same result (everything is registered) but there is no "execve":
[ 8621.430568] registered: do_execve, ret: 0
And this is my code:
static struct jprobe jprobe_hooks[] = {
{
.entry = jdo_execve,
.kp = { .symbol_name = "do_execve" }
}};
static long jdo_execve(const char *filename, const char __user *const __user *argv, const char __user *const __user *envp, struct pt_regs *regs)
{
printk(KERN_INFO "execve: %s", filename );
}
//
// registration
//
int ret, x, reg_error;
reg_error = 0;
for (x = 0; x < sizeof(jprobe_hooks) / sizeof(jprobe_hooks[0]); x++)
{
ret = register_jprobe(&jprobe_hooks[x]);
if (ret < 0)
{
printk(KERN_INFO "register_jprobe failed, returned %d, item: %s\n", ret, jprobe_hooks[x].kp.symbol_name);
reg_error++;
}
else
{
printk(KERN_INFO "registered: %s, ret: %u\n", jprobe_hooks[x].kp.symbol_name, ret);
}
}
When I do a grep on kallsyms I get on 3.2:
grep do_execv /proc/kallsyms
ffffffff81100650 T do_execve
and on 4.2:
grep do_execv /proc/kallsyms
ffffffff811d2950 T do_execve
ffffffff811d2980 T do_execveat
I even tried to change the function (because do_execve prototype has changed) to this:
static int jdo_execve(struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp)
{
int i = 0;
printk(KERN_INFO "execve: %s ", fname->name );
}
and even that didn't help.
I can set hooks on other functions like do_fork or sys_open, but not on do_execve. Why? Anybody has ideas? Why is it not working anymore?
Edit:
I'm also hooking do_execveat:
static int jdo_execveat(int fd, struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp, int flags)
Upvotes: 1
Views: 708
Reputation: 4189
There are several problems that may prevent you jprobe messages:
printk(KERN_INFO "execve: %s", filename );
with newline, thus you log buffer is not flushed.do_execve
has filename parameter as struct filename
.jprobe_return()
call and so on. Look at the samples in kernel source tree at "samples/kprobes"Try to fix it - maybe it will help.
Anyway, I tried it by myself - here is the code - and things is, indeed, looks strange. When I load the module it registers 2 jprobes - one for do_execve, another for do_execveat. But I don't see any messages when I execute programs. BUT what I do see is periodical messages like this:
jprobe: execve: /usr/lib/systemd/systemd-cgroups-agent
It means that jprobe itself works, but not for every execve
call.
So I wrote a simple C program to call execve
just to be sure it's really called and I still nothing happens execpt systemd-cgroups-agent.
Upvotes: 2