I'm fiddling with a BPF program that needs to attach to the two "getname" functions that are being called from the renameat2
syscall, defined in linux/fs/namei.c as:
SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname, unsigned int, flags)
{
return do_renameat2(olddfd, getname(oldname), newdfd, getname(newname),
flags);
}
getname
calls getname_flags
, which in turn calls strncpy_from_user
. I need to access the char __user * name
parameter, thus I tried creating kprobes, fentries and fexits (with a simple "print" program) to try and intercept all three of those functions.
With getname*, I get a lot of output meaning that my BPF program are actually being runned. Although, when calling "renameat2" (e.g. when using the linux mv
command), I get no output at all.
This is, in essence, the program I'm currently using, which doesn't get called when using the mv
command:
SEC("fentry/getname_flags")
int BPF_PROG(hijack_getname, char *filename) {
uid_t uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
if (uid == 1002) { //hardcoded uid
bpf_printk("<enter getname_flags> [%s]", filename);
}
}
If I create a BPF tracepoint program that attaches to the entry and exit of renameat2, I can clearly see that there's no "getname" call between entry and exit.
As I said, I also tried with kprobe and fexit. I can't manage to attach to strncpy_from_user
without getting some weird errors about "Os: 22 - invalid argument"
I really can't figure out what's happening, thus any help would be appreciated :,)
Solved: by analizing "vmlinux" with nm, and decompiling with "objdump", I saw that the actually called function is "getname_flags.part.0" due to compiler optimizations.