I'm trying to register a kprobe to retrieve the address of a syscall. But all my attempts seem to return -22 as the error code. The sample code below (incomplete but contains the related functions) tries to register a kernel probe for the sys_mkdir call.

It doesn't seem to matter if I specify pre or post handlers, simply registering the probe doesn't work.

Note: I'm trying to use kprobes as a replacement for the unexported kallsyms_lookup_name that is no longer exported in kernel 5.7 and above.

unsigned long lookup_name(const char *name)  
        int ret;
        struct kprobe kp;
        unsigned long retval;
        kp.symbol_name = name;
        ret = register_kprobe(&kp);     
        if (ret < 0) {
                printk(KERN_DEBUG "register_kprobe failed for symbol %s, returned %d\n", name,
                return 0;
        retval = (unsigned long)kp.addr;
        return retval;
static int __init mod_init(void)                                                              
        int (*fn)(unsigned long param);

        fn = (void*)lookup_name("__x64_sys_mkdir");   

1 Answer 1


You’re not initialising the kprobe structure in full, so you’re failing the exclusive or requirement between symbol_name and addr (point 3 in the table in the register_kprobe documentation): addr contains whatever is on the stack on function entry, which is likely to be non-zero, so both symbol_name and addr are non-zero and register_kprobe fails with EINVAL (22).

You can fix this as follows:

        int ret;
        struct kprobe kp = {
                .symbol_name = name
        unsigned long retval;

which will ensure that the other members of the structure are initialised to their default values.

  • That was indeed the issue, thank you for your solution! Commented Apr 29, 2021 at 13:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .