|
Message-ID: <1477643595.2263.168.camel@cvidal.org> Date: Fri, 28 Oct 2016 10:33:15 +0200 From: Colin Vidal <colin@...dal.org> To: Mark Rutland <mark.rutland@....com>, kernel-hardening@...ts.openwall.com Cc: "Reshetova, Elena" <elena.reshetova@...el.com>, AKASHI Takahiro <takahiro.akashi@...aro.org>, David Windsor <dave@...gbits.org>, Kees Cook <keescook@...omium.org>, Hans Liljestrand <ishkamiel@...il.com> Subject: Re: [RFC 2/2] arm: implementation for HARDENED_ATOMIC Hi Mark, On Thu, 2016-10-27 at 14:24 +0100, Mark Rutland wrote: > Hi, > > On Tue, Oct 18, 2016 at 04:59:21PM +0200, Colin Vidal wrote: > > > > This adds arm-specific code in order to support HARDENED_ATOMIC > > feature. When overflow is detected in atomic_t, atomic64_t or > > atomic_long_t, an exception is raised and call > > hardened_atomic_overflow. > > I have some comments below, but for real review this needs to go via the > linux-arm-kernel list. Thanks a lot for that! Yep, I will CC linux-arm-kernel, linux-kernel and maintainers of atomic/arm for the next RFC. I take info account your remarks for the next RFC, but I have some questions for some of them bellow. > > > > diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h > > index 66d0e21..fdaee17 100644 > > --- a/arch/arm/include/asm/atomic.h > > +++ b/arch/arm/include/asm/atomic.h > > @@ -17,18 +17,52 @@ > > #include <linux/irqflags.h> > > #include <asm/barrier.h> > > #include <asm/cmpxchg.h> > > +#include <linux/bug.h> > > > > #define ATOMIC_INIT(i) { (i) } > > > > #ifdef __KERNEL__ > > > > +#ifdef CONFIG_HARDENED_ATOMIC > > +#define HARDENED_ATOMIC_INSN "bkpt 0xf103" > > Please put the immediate in a #define somewhere. I an not sure to get what do you mean here. 0xf103 should be in a #define? (as for the A1 encoded version, for sure). > > What about thumb2 kernels? > > > > > +#define _ASM_EXTABLE(from, to) \ > > + ".pushsection __ex_table,\"a\"\n" \ > > + ".align 3\n" \ > > + ".long "#from","#to"\n" \ > > + ".popsection" > > +#define __OVERFLOW_POST \ > > + "bvc 3f\n" \ > > + "2: "HARDENED_ATOMIC_INSN"\n" \ > > + "3:\n" > > +#define __OVERFLOW_POST_RETURN \ > > + "bvc 3f\n" \ > > + "mov %0,%1\n" \ > > + "2: "HARDENED_ATOMIC_INSN"\n" \ > > + "3:\n" > > +#define __OVERFLOW_EXTABLE \ > > + "4:\n" \ > > + _ASM_EXTABLE(2b, 4b) > > +#else > > +#define __OVERFLOW_POST > > +#define __OVERFLOW_POST_RETURN > > +#define __OVERFLOW_EXTABLE > > +#endif > > + > All this should live close to the assembly using it, to make it possible > to follow. > > This may also not be the best way of structuring this code. The > additional indirection of passing this in at a high level makes it hard > to read and potentially fragile. For single instructions it was ok, but > I'm not so sure that it's ok for larger sequences like this. > I agree that is quite difficult to follow, but as Takahiro said, the current macro are already complex. Still, I will try to put those definitions closer of the code using them (for instance, just before the macro expansions?), but I am not sure that would change anything: the code using it is broke up in different area of the file anyways. Besides, I really would avoid using an extable entry, since the fixup address is never used, I am not sure it is mandatory (and it seems Takahiro does not using it, too). > > > > diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c > > index 3a2e678..ce8ee00 100644 > > --- a/arch/arm/mm/fault.c > > +++ b/arch/arm/mm/fault.c > > @@ -580,6 +580,21 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) > > const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr); > > struct siginfo info; > > > > +#ifdef CONFIG_HARDENED_ATOMIC > > + if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) { > > You'll need to justify why this isn't in the ifsr_info table. It has the > same basic shape as the usual set of handlers. > > I note that we don't seem to use SW breakpoints at all currently, and I > suspect there's a reason for that which we need to consider. > > Also, if this *must* live here, please make it a static inline with an > empty stub, rather than an ifdef'd block. > > > > > + unsigned long pc = instruction_pointer(regs); > > + unsigned int bkpt; > > + > > + if (!probe_kernel_address((const unsigned int *)pc, bkpt) && > > + cpu_to_le32(bkpt) == 0xe12f1073) { > > This appears to be the A1 encoding from the ARM ARM. What about the T1 > encoding, i.e. thumb? > > Regardless, *please* de-magic the number using a #define. > > Also, this should be le32_to_cpu -- in the end we're treating the > coverted value as cpu-native. The variable itself should be a __le32. > I must confess that I am still very confused about the code in fault.c (and the ifsr_info table). I will take time to try to understand a little bit more that code before submitting a new RFC. Still, it you have some pointers/documentations about it, I would be grateful. Thanks! Colin
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.