memflow / memflow-kvm

Linux kernel module for memflow's KVM connector
MIT License
40 stars 8 forks source link

Segementation fault on kernel module initalization #9

Open Tacodiva opened 1 year ago

Tacodiva commented 1 year ago

I have spent my afternoon unsuccessfully trying to get the kernel module to work. When I try to load it I get a segfault:

$ sudo modprobe memflow 
[1]    1805 segmentation fault (core dumped)  sudo modprobe memflow

I tried the release version and building it from this repo but both yield the same result. After the segfault the module seems to be in a weird half-loaded state and nothing really seems to work. The error is logged in dmsg and you can find the full error here, but I believe the relevant sections are:

[   40.792764] traps: Missing ENDBR: kallsyms_lookup_name+0x4/0xd0
[   40.792770] kernel BUG at arch/x86/kernel/traps.c:255!
[   40.792775] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
...
[   40.792815]  ? kallsyms_lookup_name+0x4/0xd0
[   40.792818]  memflow_init+0x25/0xb0 [memflow 727e9b5a735aa1e5b976faa4c5d2f17ff899d55f]
[   40.792823]  ? __pfx_init_module+0x10/0x10 [memflow 727e9b5a735aa1e5b976faa4c5d2f17ff899d55f]
[   40.792826]  do_one_initcall+0x5a/0x240
[   40.792830]  do_init_module+0x4a/0x200
[   40.792833]  __do_sys_init_module+0x17f/0x1b0
[   40.792835]  do_syscall_64+0x5c/0x90
...

My kernel is 6.2.13-arch1-1 and both CONFIG_KALLSYMS=y, and CONFIG_KALLSYMS_ALL=y are present in my /proc/config.gz.

Tacodiva commented 1 year ago

Ok I spent the last too long trying to fix this and have officially given up. For some reason I can't decipher, on my laptop using kprobes to get the address of kallsyms_lookup_name just seems to give the wrong pointer (it gives me kallsyms_lookup_name+0x4/0xd0). I thought if I subtracted four from that it could work but that also segfaults. I tried using a completely different method of finding kallsyms_lookup_name from here but that also gave pointers which segfaulted. Every time I tried something I had to reboot my laptop because the segfault messes everything up so badly that I can't unload the module (even with -f) so I just have to reboot to try again. I'm officially out of ideas and need someone who knows what they're doing to help.

TLDR: I tried my best :sob:

nexensys commented 1 year ago

Best of luck, I wish I knew Linux better XD

Tacodiva commented 1 year ago

Finally I (or more accurately someone on stackoverflow) worked out the problem. You can fix this by using the ibt=off kernel parameter.

Because kallsyms_lookup_name is not exported, it does not contain the ENDBR instruction. ENDBR is an instruction for intel's security feature 'IBT'. With IBT enabled you cannot indirectly branch to any point in memory, you can only branch to places that start with the ENDBR instruction, hence when the module indirectly branches to kallsyms_lookup_name, it crashes. That kernel parameter disables the IBT security feature, so it's not an ideal solution but it's a solution nonetheless. If a better solution cannot be found, this should probably be mentioned in the README.

ko1N commented 1 month ago

I can't reproduce this on linux 6.11.1. Can you confirm this is still an issue on newer kernels?

Tacodiva commented 1 month ago

I can't reproduce this on linux 6.11.1. Can you confirm this is still an issue on newer kernels?

Does your system/processor have IBT? I can't imagine this has been resolved, though I can't test it at the moment.