0

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, ret); return 0; } retval = (unsigned long)kp.addr; unregister_kprobe(&kp); return retval; } static int __init mod_init(void) { int (*fn)(unsigned long param); fn = (void*)lookup_name("__x64_sys_mkdir"); } 

1 Answer 1

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.

1
  • 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.