Linux kernel 从ftrace处理程序返回原始函数时还原任务pt_regs
通过内核模块(LKM),linux内核Linux kernel 从ftrace处理程序返回原始函数时还原任务pt_regs,linux-kernel,ftrace,Linux Kernel,Ftrace,通过内核模块(LKM),linux内核ftrace函数允许您设置ftrace\u OPS\u FL\u SAVE\u REGS和ftrace\u OPS\u FL\u IPMODIFY标志,基本上允许您完全重定向任何可以找到符号地址的内核函数,如下所示: static void notrace my_ftrace_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *fops, struct p
ftrace
函数允许您设置ftrace\u OPS\u FL\u SAVE\u REGS
和ftrace\u OPS\u FL\u IPMODIFY
标志,基本上允许您完全重定向任何可以找到符号地址的内核函数,如下所示:
static void notrace my_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *fops, struct pt_regs *regs) {
regs->ip = new_addr;
}
其中new\u addr
是新函数的地址。kpatch
工具使用此功能,但从未返回原始功能
如果在new\u addr
指向的函数末尾,我尝试以下操作:
task_pt_regs(current)->ip = orig_addr + MCOUNT_INSN_SIZE;
有些函数进行时不会出现问题,但大多数函数会导致调用过程出现故障
ftrace
函数具有内置代码,可在返回到原始函数时恢复当前任务的pt_regs
,这就是为什么我可以转到自己的函数并拥有参数而不会出现问题的原因。但是,在代码的这一点上,ftrace
不再涉及。我如何告诉内核不要重置当前寄存器,这样函数就可以在新的返回地址使用它们呢?发布这篇文章后,我想也许我可以直接从ftrace处理程序中的pt_regs*regs
指针读取参数。事实证明,你可以。通过不重定向到另一个函数,您可以保留寄存器和返回地址,同时决定是否从处理程序本身返回:
int donotexec(void) {
return -EACCES;
}
static void notrace my_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *fops, struct pt_regs *regs) {
struct linux_binprm *bprm = (struct linux_binprm *)regs->di;
if (bprm->file)
if (allowed_to_exec(bprm->file))
regs->ip = (unsigned long)donotexec;
}
此函数钩住security\u bprm\u check
,其中allowed\u to\u exec
是另一个函数,用于检查从regs->di
寄存器读取的bprm->file
这是依赖于arch的(请参见
arch/x86/include/asm/ptrace.h
中的内核pt_regs
结构),并且限制为5个函数参数。在发布这篇文章之后,我想也许我可以直接从ftrace处理程序中的pt_regs*regs
指针读取参数。事实证明,你可以。通过不重定向到另一个函数,您可以保留寄存器和返回地址,同时决定是否从处理程序本身返回:
int donotexec(void) {
return -EACCES;
}
static void notrace my_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *fops, struct pt_regs *regs) {
struct linux_binprm *bprm = (struct linux_binprm *)regs->di;
if (bprm->file)
if (allowed_to_exec(bprm->file))
regs->ip = (unsigned long)donotexec;
}
此函数钩住security\u bprm\u check
,其中allowed\u to\u exec
是另一个函数,用于检查从regs->di
寄存器读取的bprm->file
这取决于arch(请参见arch/x86/include/asm/ptrace.h
中内核的pt_regs
结构),并且限制为5个函数参数