简体   繁体   中英

Jprobe doesn't monitor all `do_execve` calls

I know there has been a question about this in the past, but I didn't find a solution.

I'm writing the next kernel module to trace do_exec calls. AFAIK every new process image (not creation) should be loaded like this, so I figure I can trace down all executions with this jprobe .

Unfortunately, the only outputs from this jprobe are these:

execve called /usr/lib/systemd/systemd-cgroups-agent by kworker/u8:3

My module code is as follow:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/fs.h>

static long jdo_execve(struct filename *filename, 
        const char __user *const __user __argv, 
        const char __user *const __user __envp)
{
    const char *name = filename->name;
    printk("execve called %s by %s\n", name, current->comm);
    jprobe_return();
    return 0;
}

static struct jprobe execve_jprobe = {
    .entry          = jdo_execve,
    .kp = {
        .symbol_name    = "do_execve",
    },
};

static int __init jprobe_init(void)
{
    int ret;

    ret = register_jprobe(&execve_jprobe);
    if (ret < 0) {
        printk(KERN_INFO "register_jprobe failed, returned %d\n", ret);
        return -1;
    }
    return 0;
}

static void __exit jprobe_exit(void)
{
    unregister_jprobe(&execve_jprobe);
    printk(KERN_INFO "jprobe at %p unregistered\n", write_jprobe.kp.addr);
}

module_init(jprobe_init)
module_exit(jprobe_exit)
MODULE_LICENSE("GPL");

I'm using CentOS 7, kernel version 3.10.0-514.el7.x86_64

Any help is appreciated!

The code at hand is:

SYSCALL_DEFINE3(execve,
                const char __user *, filename,
                const char __user *const __user *, argv,
                const char __user *const __user *, envp)
{
        return do_execve(getname(filename), argv, envp);
}

and:

int do_execve(struct filename *filename,
        const char __user *const __user *__argv,
        const char __user *const __user *__envp)
{
        struct user_arg_ptr argv = { .ptr.native = __argv };
        struct user_arg_ptr envp = { .ptr.native = __envp };
        return do_execve_common(filename, argv, envp);
}

Given how short the function is the first obvious suspicion is that it got inlined in the execve entry point. Disassembling confirms the suspicion:

0xffffffff811e6e20 <sys_execve>:        nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffff811e6e25 <sys_execve+0x5>:    push   %rbp
0xffffffff811e6e26 <sys_execve+0x6>:    mov    %rsp,%rbp
0xffffffff811e6e29 <sys_execve+0x9>:    push   %r12
0xffffffff811e6e2b <sys_execve+0xb>:    mov    %rdx,%r12
0xffffffff811e6e2e <sys_execve+0xe>:    push   %rbx
0xffffffff811e6e2f <sys_execve+0xf>:    mov    %rsi,%rbx
0xffffffff811e6e32 <sys_execve+0x12>:   callq  0xffffffff811ef380 <getname>
0xffffffff811e6e37 <sys_execve+0x17>:   mov    %r12,%r8
0xffffffff811e6e3a <sys_execve+0x1a>:   mov    %rbx,%rdx
0xffffffff811e6e3d <sys_execve+0x1d>:   xor    %ecx,%ecx
0xffffffff811e6e3f <sys_execve+0x1f>:   xor    %esi,%esi
0xffffffff811e6e41 <sys_execve+0x21>:   mov    %rax,%rdi
0xffffffff811e6e44 <sys_execve+0x24>:   callq  0xffffffff811e6520 <do_execve_common>
0xffffffff811e6e49 <sys_execve+0x29>:   pop    %rbx
0xffffffff811e6e4a <sys_execve+0x2a>:   pop    %r12
0xffffffff811e6e4c <sys_execve+0x2c>:   cltq   
0xffffffff811e6e4e <sys_execve+0x2e>:   pop    %rbp
0xffffffff811e6e4f <sys_execve+0x2f>:   retq   

Thus, you are not seeing most "calls" to do_execve because the are not any in the code path you are interested in.

Another approach to debug this would be try to put a probe on something deeper or higher in the stack.

I have to ask why are you playing with jprobes or the kernel in general. So far it seems you are a beginner programmer and should not play with it just yet. In particular it is unlikely you will be able to write kernel code (and this includes jprobes) which obeys all the rules and be able to explain why it does. It is too easy to create code which in insufficient testing appears to work, but is broken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM