From: Naveen N. Rao <hidden> Date: 2017-10-23 16:37:55
Per Documentation/kprobes.txt, probe handlers need to be invoked with
preemption disabled. Update optimized_callback() to do so. Also move
get_kprobe_ctlblk() invocation post preemption disable, since it
accesses pre-cpu data.
This was not an issue so far since optprobes wasn't selected if
CONFIG_PREEMPT was enabled. Commit a30b85df7d599f ("kprobes: Use
synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y") changes
this.
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/optprobes.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
@@ -115,7 +115,6 @@ static unsigned long can_optimize(struct kprobe *p)staticvoidoptimized_callback(structoptimized_kprobe*op,structpt_regs*regs){-structkprobe_ctlblk*kcb=get_kprobe_ctlblk();unsignedlongflags;/* This is possible if op is under delayed unoptimizing */
From: Naveen N. Rao <hidden> Date: 2017-10-23 16:37:59
Per Documentation/kprobes.txt, we don't necessarily need to disable
interrupts before invoking the kprobe handlers. Masami submitted
similar changes for x86 via commit a19b2e3d783964 ("kprobes/x86: Remove
IRQ disabling from ftrace-based/optimized kprobes"). Do the same for
powerpc.
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/kprobes-ftrace.c | 10 ++--------
arch/powerpc/kernel/optprobes.c | 10 ----------
2 files changed, 2 insertions(+), 18 deletions(-)
@@ -75,11 +75,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,{structkprobe*p;structkprobe_ctlblk*kcb;-unsignedlongflags;-/* Disable irq for emulating a breakpoint and avoiding preempt */-local_irq_save(flags);-hard_irq_disable();preempt_disable();p=get_kprobe((kprobe_opcode_t*)nip);
@@ -105,16 +101,14 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,else{/**Ifpre_handlerreturns!0,itsetsregs->nipand-*resetscurrentkprobe.Inthiscase,westillneed-*torestoreirq,butnotpreemption.+*resetscurrentkprobe.Inthiscase,weshouldnot+*re-enablepreemption.*/-local_irq_restore(flags);return;}}end:preempt_enable_no_resched();-local_irq_restore(flags);}NOKPROBE_SYMBOL(kprobe_ftrace_handler);
@@ -115,14 +115,10 @@ static unsigned long can_optimize(struct kprobe *p)staticvoidoptimized_callback(structoptimized_kprobe*op,structpt_regs*regs){-unsignedlongflags;-/* This is possible if op is under delayed unoptimizing */if(kprobe_disabled(&op->kp))return;-local_irq_save(flags);-hard_irq_disable();preempt_disable();if(kprobe_running()){
From: Naveen N. Rao <hidden> Date: 2017-10-23 16:38:01
Commit 3cdfcbfd32b9d ("powerpc: Change analyse_instr so it doesn't
modify *regs") introduced emulate_update_regs() to perform part of what
emulate_step() was doing earlier. However, this function was not added
to the kprobes blacklist. Add it so as to prevent it from being probed.
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/lib/sstep.c | 1 +
1 file changed, 1 insertion(+)
From: Naveen N. Rao <hidden> Date: 2017-10-23 16:38:06
Use safer string manipulation functions when dealing with a
user-provided string in kprobe_lookup_name().
Reported-by: David Laight <redacted>
Signed-off-by: Naveen N. Rao <redacted>
---
arch/powerpc/kernel/kprobes.c | 47 ++++++++++++++++++-------------------------
1 file changed, 20 insertions(+), 27 deletions(-)
@@ -53,7 +53,7 @@ bool arch_within_kprobe_blacklist(unsigned long addr)kprobe_opcode_t*kprobe_lookup_name(constchar*name,unsignedintoffset){-kprobe_opcode_t*addr;+kprobe_opcode_t*addr=NULL;#ifdef PPC64_ELF_ABI_v2/* PPC64 ABIv2 needs local entry point */
@@ -85,36 +85,29 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)*Alsohandle<module:symbol>format.*/chardot_name[MODULE_NAME_LEN+1+KSYM_NAME_LEN];-constchar*modsym;booldot_appended=false;-if((modsym=strchr(name,':'))!=NULL){-modsym++;-if(*modsym!='\0'&&*modsym!='.'){-/* Convert to <module:.symbol> */-strncpy(dot_name,name,modsym-name);-dot_name[modsym-name]='.';-dot_name[modsym-name+1]='\0';-strncat(dot_name,modsym,-sizeof(dot_name)-(modsym-name)-2);-dot_appended=true;-}else{-dot_name[0]='\0';-strncat(dot_name,name,sizeof(dot_name)-1);-}-}elseif(name[0]!='.'){-dot_name[0]='.';-dot_name[1]='\0';-strncat(dot_name,name,KSYM_NAME_LEN-2);+constchar*c;+ssize_tret=0;+intlen=0;++if((c=strnchr(name,MODULE_NAME_LEN,':'))!=NULL){+c++;+len=c-name;+memcpy(dot_name,name,len);+}else+c=name;++if(*c!='\0'&&*c!='.'){+dot_name[len++]='.';dot_appended=true;-}else{-dot_name[0]='\0';-strncat(dot_name,name,KSYM_NAME_LEN-1);}-addr=(kprobe_opcode_t*)kallsyms_lookup_name(dot_name);-if(!addr&&dot_appended){-/* Let's try the original non-dot symbol lookup */+ret=strscpy(dot_name+len,c,KSYM_NAME_LEN);+if(ret>0)+addr=(kprobe_opcode_t*)kallsyms_lookup_name(dot_name);++/* Fallback to the original non-dot symbol lookup */+if(!addr&&dot_appended)addr=(kprobe_opcode_t*)kallsyms_lookup_name(name);-}#elseaddr=(kprobe_opcode_t*)kallsyms_lookup_name(name);#endif
On Mon, 23 Oct 2017 22:07:38 +0530
"Naveen N. Rao" [off-list ref] wrote:
Per Documentation/kprobes.txt, probe handlers need to be invoked with
preemption disabled. Update optimized_callback() to do so. Also move
get_kprobe_ctlblk() invocation post preemption disable, since it
accesses pre-cpu data.
This was not an issue so far since optprobes wasn't selected if
CONFIG_PREEMPT was enabled. Commit a30b85df7d599f ("kprobes: Use
synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y") changes
this.
Actually, if you local_irq_save(), it also disables preempt. So unless you
enables irqs, it should be safe.
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Thank you,
@@ -115,7 +115,6 @@ static unsigned long can_optimize(struct kprobe *p)staticvoidoptimized_callback(structoptimized_kprobe*op,structpt_regs*regs){-structkprobe_ctlblk*kcb=get_kprobe_ctlblk();unsignedlongflags;/* This is possible if op is under delayed unoptimizing */
On Mon, 23 Oct 2017 22:07:39 +0530
"Naveen N. Rao" [off-list ref] wrote:
Per Documentation/kprobes.txt, we don't necessarily need to disable
interrupts before invoking the kprobe handlers. Masami submitted
similar changes for x86 via commit a19b2e3d783964 ("kprobes/x86: Remove
IRQ disabling from ftrace-based/optimized kprobes"). Do the same for
powerpc.
Yes, and this requires to make preempt disable :)
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Thank you!
@@ -75,11 +75,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,{structkprobe*p;structkprobe_ctlblk*kcb;-unsignedlongflags;-/* Disable irq for emulating a breakpoint and avoiding preempt */-local_irq_save(flags);-hard_irq_disable();preempt_disable();p=get_kprobe((kprobe_opcode_t*)nip);
@@ -105,16 +101,14 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,else{/**Ifpre_handlerreturns!0,itsetsregs->nipand-*resetscurrentkprobe.Inthiscase,westillneed-*torestoreirq,butnotpreemption.+*resetscurrentkprobe.Inthiscase,weshouldnot+*re-enablepreemption.*/-local_irq_restore(flags);return;}}end:preempt_enable_no_resched();-local_irq_restore(flags);}NOKPROBE_SYMBOL(kprobe_ftrace_handler);
@@ -115,14 +115,10 @@ static unsigned long can_optimize(struct kprobe *p)staticvoidoptimized_callback(structoptimized_kprobe*op,structpt_regs*regs){-unsignedlongflags;-/* This is possible if op is under delayed unoptimizing */if(kprobe_disabled(&op->kp))return;-local_irq_save(flags);-hard_irq_disable();preempt_disable();if(kprobe_running()){
On Mon, 23 Oct 2017 22:07:41 +0530
"Naveen N. Rao" [off-list ref] wrote:
Use safer string manipulation functions when dealing with a
user-provided string in kprobe_lookup_name().
What would you mean "safer" here? using strnchr()?
Could you please show at least an example case that causes problem in original code.
And have one comment below:
On Mon, 23 Oct 2017 22:07:40 +0530
"Naveen N. Rao" [off-list ref] wrote:
Commit 3cdfcbfd32b9d ("powerpc: Change analyse_instr so it doesn't
modify *regs") introduced emulate_update_regs() to perform part of what
emulate_step() was doing earlier. However, this function was not added
to the kprobes blacklist. Add it so as to prevent it from being probed.
Looks good to me.
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Thank you!
From: Naveen N. Rao <hidden> Date: 2017-10-27 11:27:30
On 2017/10/25 02:18AM, Masami Hiramatsu wrote:
On Mon, 23 Oct 2017 22:07:38 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Per Documentation/kprobes.txt, probe handlers need to be invoked with
preemption disabled. Update optimized_callback() to do so. Also move
get_kprobe_ctlblk() invocation post preemption disable, since it
accesses pre-cpu data.
This was not an issue so far since optprobes wasn't selected if
CONFIG_PREEMPT was enabled. Commit a30b85df7d599f ("kprobes: Use
synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y") changes
this.
Actually, if you local_irq_save(), it also disables preempt. So unless you
enables irqs, it should be safe.
I think we still need to disable preemption explicitly (at least on
powerpc, disabling irqs doesn't increment preempt count). See commit
6baea433bc84cd ("powerpc/jprobes: Disable preemption when triggered
through ftrace") for example.
We need to ensure preempt count is properly balanced for our usage
across KPROBES_ON_FTRACE, OPTPROBES and POTS (plain old trap system ;-)
From: Naveen N. Rao <hidden> Date: 2017-10-27 11:34:52
On 2017/10/25 04:35PM, Masami Hiramatsu wrote:
On Mon, 23 Oct 2017 22:07:41 +0530
"Naveen N. Rao" [off-list ref] wrote:
quoted
Use safer string manipulation functions when dealing with a
user-provided string in kprobe_lookup_name().
What would you mean "safer" here? using strnchr()?
Could you please show at least an example case that causes problem in original code.
Yes, essentially about using bounded string operations. Since the 'name'
parameter is provided by user, it's better to ensure it is within
limits. Granted, this isn't a big deal since user needs to be root for
accessing this API, but we felt it is good to clean up this code.
From: Michael Ellerman <hidden> Date: 2017-11-14 11:12:09
On Mon, 2017-10-23 at 16:37:38 UTC, "Naveen N. Rao" wrote:
Per Documentation/kprobes.txt, probe handlers need to be invoked with
preemption disabled. Update optimized_callback() to do so. Also move
get_kprobe_ctlblk() invocation post preemption disable, since it
accesses pre-cpu data.
This was not an issue so far since optprobes wasn't selected if
CONFIG_PREEMPT was enabled. Commit a30b85df7d599f ("kprobes: Use
synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y") changes
this.
Signed-off-by: Naveen N. Rao <redacted>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>