每次使用 rdmsrl(MSR_LSTAR, system_call) 时,system_call 值都不同

system_call value is different each time when I use rdmsrl(MSR_LSTAR, system_call)

我正在写一个 lkm 来获取 sys_call_table 地址,我正在尝试通过 IDT 获取它(我已经测试了其他方法并且它们有效)。问题是,当我使用 rdmsrl 获取寄存器 MSR_LSTAR 时,每次都不一样。

我在 Ubuntu 18.04.1 和内核 4.15.0-51 中尝试了函数 rdmsrl (MSR_LSTAR) 和 asm 语句。

asm("rdmsr" : "=a" (low), "=d" (high) : "c" (IA32_LSTAR));
system_call = (void*)(((long)high<<32) | low);
printk(KERN_INFO "system_call: 0x%llx", system_call);
rdmsrl(MSR_LSTAR, sct_off);
printk("sct_off: %016llx\n", sct_off);

结果如下:

system_call: 0xfffffe0000006000
system_call: 0xfffffe000008a000
system_call: 0xfffffe0000032000

你有CONFIG_RETPOLINE=y启用吗? (通过 cat /usr/src/`uname -r`/.config | grep RETPOLINE 检查)。如果是这样,对于启用内核页面 Table 隔离的 CPU,MSR_LSTAR 为您的内核版本保留 trampoline per-cpu entry SYSCALL64_entry_trampoline instead of the standard entry_SYSCALL_64