|
Message-Id: <1585906281.fbqgtc3kpy.naveen@linux.ibm.com> Date: Fri, 03 Apr 2020 15:06:25 +0530 From: "Naveen N. Rao" <naveen.n.rao@...ux.ibm.com> To: linuxppc-dev@...ts.ozlabs.org, Russell Currey <ruscur@...sell.cc> Cc: ajd@...ux.ibm.com, dja@...ens.net, kernel-hardening@...ts.openwall.com, npiggin@...il.com Subject: Re: [PATCH v8 2/7] powerpc/kprobes: Mark newly allocated probes as RO Russell Currey wrote: > On Fri, 2020-04-03 at 00:18 +0530, Naveen N. Rao wrote: >> Naveen N. Rao wrote: >> > Russell Currey wrote: >> > > With CONFIG_STRICT_KERNEL_RWX=y and CONFIG_KPROBES=y, there will >> > > be one >> > > W+X page at boot by default. This can be tested with >> > > CONFIG_PPC_PTDUMP=y and CONFIG_PPC_DEBUG_WX=y set, and checking >> > > the >> > > kernel log during boot. >> > > >> > > powerpc doesn't implement its own alloc() for kprobes like other >> > > architectures do, but we couldn't immediately mark RO anyway >> > > since we do >> > > a memcpy to the page we allocate later. After that, nothing >> > > should be >> > > allowed to modify the page, and write permissions are removed >> > > well >> > > before the kprobe is armed. >> > > >> > > The memcpy() would fail if >1 probes were allocated, so use >> > > patch_instruction() instead which is safe for RO. >> > > >> > > Reviewed-by: Daniel Axtens <dja@...ens.net> >> > > Signed-off-by: Russell Currey <ruscur@...sell.cc> >> > > Signed-off-by: Christophe Leroy <christophe.leroy@....fr> >> > > --- >> > > arch/powerpc/kernel/kprobes.c | 17 +++++++++++++---- >> > > 1 file changed, 13 insertions(+), 4 deletions(-) >> > > >> > > diff --git a/arch/powerpc/kernel/kprobes.c >> > > b/arch/powerpc/kernel/kprobes.c >> > > index 81efb605113e..fa4502b4de35 100644 >> > > --- a/arch/powerpc/kernel/kprobes.c >> > > +++ b/arch/powerpc/kernel/kprobes.c >> > > @@ -24,6 +24,8 @@ >> > > #include <asm/sstep.h> >> > > #include <asm/sections.h> >> > > #include <linux/uaccess.h> >> > > +#include <linux/set_memory.h> >> > > +#include <linux/vmalloc.h> >> > > >> > > DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; >> > > DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); >> > > @@ -102,6 +104,16 @@ kprobe_opcode_t *kprobe_lookup_name(const >> > > char *name, unsigned int offset) >> > > return addr; >> > > } >> > > >> > > +void *alloc_insn_page(void) >> > > +{ >> > > + void *page = vmalloc_exec(PAGE_SIZE); >> > > + >> > > + if (page) >> > > + set_memory_ro((unsigned long)page, 1); >> > > + >> > > + return page; >> > > +} >> > > + >> > >> > This crashes for me with KPROBES_SANITY_TEST during the kretprobe >> > test. >> >> That isn't needed to reproduce this. After bootup, disabling >> optprobes >> also shows the crash with kretprobes: >> sysctl debug.kprobes-optimization=0 >> >> The problem happens to be with patch_instruction() in >> arch_prepare_kprobe(). During boot, on kprobe init, we register a >> probe >> on kretprobe_trampoline for use with kretprobes (see >> arch_init_kprobes()). This results in an instruction slot being >> allocated, and arch_prepare_kprobe() to be called for copying the >> instruction (nop) at kretprobe_trampoline. patch_instruction() is >> failing resulting in corrupt instruction which we try to >> emulate/single >> step causing the crash. > > OK I think I've fixed it, KPROBES_SANITY_TEST passes too. I'd > appreciate it if you could test v9, and thanks again for finding this - > very embarrassing bug on my side. Great! Thanks. I think I should also add appropriate error checking to kprobes' use of patch_instruction() which would have caught this much more easily. On a related note, I notice that x86 seems to prefer not having any RWX pages, and so they continue to do 'module_alloc()' followed by 'set_memory_ro()' and then 'set_memory_x()'. Is that something worth following for powerpc? - Naveen
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.