Re: [PATCH] arm64: defconfig: update and enable CONFIG_RANDOMIZE_BASE

From: Ard Biesheuvel
Date: Tue Jun 25 2019 - 12:25:08 EST


On Tue, 25 Jun 2019 at 18:03, Catalin Marinas <catalin.marinas@xxxxxxx> wrote:
>
> On Tue, Jun 25, 2019 at 05:42:49PM +0200, Ard Biesheuvel wrote:
> > On Tue, 25 Jun 2019 at 17:39, Catalin Marinas <catalin.marinas@xxxxxxx> wrote:
> > > On Mon, Jun 24, 2019 at 12:06:18PM +0200, Ard Biesheuvel wrote:
> > > > On Mon, 24 Jun 2019 at 11:57, Will Deacon <will@xxxxxxxxxx> wrote:
> > > > > Thanks for having a look. It could be that we've fixed the issue Catalin was
> > > > > running into in the past -- he was going to see if the problem persists with
> > > > > mainline, since it was frequent enough that it was causing us to ignore the
> > > > > results from our testing infrastructure when RANDOMIZE_BASE=y.
> > > >
> > > > I had no idea this was the case. I can look into it if we are still
> > > > seeing failures.
> > >
> > > I've seen the panic below with 5.2-rc1, defconfig + RANDOMIZE_BASE=y in
> > > a guest on TX2. It takes a few tries to trigger just with kaslr,
> > > enabling lots of other DEBUG_* options makes the failures more
> > > deterministic. I can't really say it's kaslr's fault here, only that I
> > > used to consistently get it in this configuration. For some reason, I
> > > can no longer reproduce it on arm64 for-next/core (or maybe it just
> > > takes more tries and my script doesn't catch this).
> > >
> > > The fault is in the ip_tables module, the __this_cpu_read in
> > > xt_write_recseq_begin() inlined in ipt_do_table(). The disassembled
> > > sequence in my build:
> > >
> > > 0000000000000188 <ipt_do_table>:
> > > ...
> > > 258: d538d080 mrs x0, tpidr_el1
> > > 25c: aa1303f9 mov x25, x19
> > > 260: b8606b34 ldr w20, [x25, x0]
> >
> > This was fixed recently by
> >
> > arm64/kernel: kaslr: reduce module randomization range to 2 GB
> >
> > (and arm64/module: deal with ambiguity in PRELxx relocation ranges to
> > some extent)
>
> Thanks. This explains it.
>
> And another weird case that triggers only with 64K pages, KASan and
> KASLR combination (guest on TX2). My test script modprobes all the
> modules it finds installed (including some test kernel modules like lock
> torture). At some point during modprobing, vmalloc trips over the
> WARN_ON(!pte_none(*pte)) in vmap_pte_range():
>

When KASAN and KASLR are both enabled, modules are allocated in the
dedicated module window, since the vmalloc space is already shadowed
by KASAN zero pages and so the modules must be kept out of it. since
they have their own real shadow pages that are allocated on demand.

Looking at the backtrace, it seems like the failure may be due to the
shadow space clashing, probably because the top of the module region
exceeds MODULES_END.

Does the below help at all? (patch soup courtesy of gmail, apologies)


diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index f713e2fc4d75..7e94e1f948c9 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -32,6 +32,7 @@

void *module_alloc(unsigned long size)
{
+ u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;
gfp_t gfp_mask = GFP_KERNEL;
void *p;

@@ -39,9 +40,11 @@ void *module_alloc(unsigned long size)
if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
gfp_mask |= __GFP_NOWARN;

+ if (IS_ENABLED(CONFIG_KASAN))
+ module_alloc_end = MODULES_END;
+
p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
- module_alloc_base + MODULES_VSIZE,
- gfp_mask, PAGE_KERNEL_EXEC, 0,
+ module_alloc_end, gfp_mask, PAGE_KERNEL_EXEC, 0,
NUMA_NO_NODE, __builtin_return_address(0));

if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&