[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 03 Mar 2022 15:15:14 +0530
From: "Naveen N. Rao" <naveen.n.rao@...ux.vnet.ibm.com>
To: Peter Zijlstra <peterz@...radead.org>,
Steven Rostedt <rostedt@...dmis.org>
Cc: alexei.starovoitov@...il.com, alyssa.milburn@...el.com,
andrew.cooper3@...rix.com, hjl.tools@...il.com,
joao@...rdrivepizza.com, jpoimboe@...hat.com,
keescook@...omium.org, linux-kernel@...r.kernel.org,
mark.rutland@....com, mbenes@...e.cz,
Masami Hiramatsu <mhiramat@...nel.org>,
ndesaulniers@...gle.com, samitolvanen@...gle.com, x86@...nel.org
Subject: Re: [PATCH v2 12/39] x86/ibt,ftrace: Search for __fentry__ location
Peter Zijlstra wrote:
> On Wed, Mar 02, 2022 at 02:47:16PM -0500, Steven Rostedt wrote:
>> Note, I just pulled this patch, and I hit this warning:
>>
>> WARNING: CPU: 0 PID: 6965 at arch/x86/kernel/kprobes/core.c:205 recover_probed_instruction+0x8f/0xa0
>>
>> static unsigned long
>> __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
>> {
>> struct kprobe *kp;
>> unsigned long faddr;
>>
>> kp = get_kprobe((void *)addr);
>> faddr = ftrace_location(addr);
>> /*
>> * Addresses inside the ftrace location are refused by
>> * arch_check_ftrace_location(). Something went terribly wrong
>> * if such an address is checked here.
>> */
>> if (WARN_ON(faddr && faddr != addr)) <<---- HERE
>> return 0UL;
>
> Ha! so a bunch of IRC later I figured out how it is possible you hit
> this with just the patch on and how I legitimately hit this and what to
> do about it.
>
> Your problem seems to be that we got ftrace_location() wrong in that
> lookup_rec()'s end argument is inclusive, hence we need:
>
> lookup_rec(ip, ip + size - 1)
>
> Now, the above thing asserts that:
>
> ftrace_location(x) == {0, x}
>
> and that is genuinely false in my case, I get x+4 as additional possible
> output. So I think I need the below change to go on top of all I have:
>
>
> diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
> index 7f0ce42f8ff9..4c13406e0bc4 100644
> --- a/arch/x86/kernel/kprobes/core.c
> +++ b/arch/x86/kernel/kprobes/core.c
> @@ -198,13 +198,14 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
>
> kp = get_kprobe((void *)addr);
> faddr = ftrace_location(addr);
> +
> /*
> - * Addresses inside the ftrace location are refused by
> - * arch_check_ftrace_location(). Something went terribly wrong
> - * if such an address is checked here.
> + * In case addr maps to sym+0 ftrace_location() might return something
> + * other than faddr. In that case consider it the same as !faddr.
> */
> - if (WARN_ON(faddr && faddr != addr))
> - return 0UL;
> + if (faddr && faddr != addr)
> + faddr = 0;
> +
> /*
> * Use the current code if it is not modified by Kprobe
> * and it cannot be modified by ftrace.
I hit this issue yesterday in kprobe generic code in check_ftrace_location().
In both these scenarios, we just want to check if a particular instruction is
reserved by ftrace. ftrace_location_range() should still work for that
purpose, so that may be the easier fix:
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 066fa644e9dfa3..ee3cd035403ca2 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1596,7 +1596,7 @@ static int check_ftrace_location(struct kprobe *p)
{
unsigned long ftrace_addr;
- ftrace_addr = ftrace_location((unsigned long)p->addr);
+ ftrace_addr = ftrace_location_range((unsigned long)p->addr, (unsigned long)p->addr);
if (ftrace_addr) {
#ifdef CONFIG_KPROBES_ON_FTRACE
/* Given address is not on the instruction boundary */
- Naveen
Powered by blists - more mailing lists