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");
}
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.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments