From: Will Deacon <will.deacon@arm.com>
To: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
linux@armlinux.org.uk, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v3 1/4] arm64: compat: Alloc separate pages for vectors and sigpage
Date: Fri, 12 Apr 2019 12:55:07 +0100 [thread overview]
Message-ID: <20190412115507.GA28260@fuggles.cambridge.arm.com> (raw)
In-Reply-To: <7a4e4984-5448-5b93-5270-5b27abbec7f7@arm.com>
[+rmk]
On Fri, Apr 12, 2019 at 12:08:30PM +0100, Vincenzo Frascino wrote:
> On 10/04/2019 19:10, Will Deacon wrote:
> > On Tue, Apr 02, 2019 at 05:27:54PM +0100, Vincenzo Frascino wrote:
> >> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> >> index 5d9ce62bdebd..07c873fce961 100644
> >> --- a/arch/arm64/include/asm/processor.h
> >> +++ b/arch/arm64/include/asm/processor.h
> >> @@ -78,9 +78,9 @@
> >> #endif /* CONFIG_ARM64_FORCE_52BIT */
> >>
> >> #ifdef CONFIG_COMPAT
> >> -#define AARCH32_VECTORS_BASE 0xffff0000
> >> +#define AARCH32_KUSER_BASE 0xffff0000
> >> #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
> >> - AARCH32_VECTORS_BASE : STACK_TOP_MAX)
> >> + AARCH32_KUSER_BASE : STACK_TOP_MAX)
> >> #else
> >> #define STACK_TOP STACK_TOP_MAX
> >> #endif /* CONFIG_COMPAT */
> >> diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
> >> index 81abea0b7650..58e288aaf0ba 100644
> >> --- a/arch/arm64/include/asm/signal32.h
> >> +++ b/arch/arm64/include/asm/signal32.h
> >> @@ -20,8 +20,6 @@
> >> #ifdef CONFIG_COMPAT
> >> #include <linux/compat.h>
> >>
> >> -#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500
> >> -
> >> int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
> >> struct pt_regs *regs);
> >> int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
> >> diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
> >> index cb7800acd19f..3846a1b710b5 100644
> >> --- a/arch/arm64/kernel/signal32.c
> >> +++ b/arch/arm64/kernel/signal32.c
> >> @@ -379,6 +379,7 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
> >> compat_ulong_t retcode;
> >> compat_ulong_t spsr = regs->pstate & ~(PSR_f | PSR_AA32_E_BIT);
> >> int thumb;
> >> + void *sigreturn_base;
> >>
> >> /* Check if the handler is written for ARM or Thumb */
> >> thumb = handler & 1;
> >> @@ -399,12 +400,12 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
> >> } else {
> >> /* Set up sigreturn pointer */
> >> unsigned int idx = thumb << 1;
> >> + sigreturn_base = current->mm->context.vdso;
> >>
> >> if (ka->sa.sa_flags & SA_SIGINFO)
> >> idx += 3;
> >>
> >> - retcode = AARCH32_VECTORS_BASE +
> >> - AARCH32_KERN_SIGRET_CODE_OFFSET +
> >> + retcode = ptr_to_compat(sigreturn_base) +
> >> (idx << 2) + thumb;
> >> }
> >>
> >> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> >> index 2d419006ad43..16f8fce5c501 100644
> >> --- a/arch/arm64/kernel/vdso.c
> >> +++ b/arch/arm64/kernel/vdso.c
> >> @@ -1,5 +1,7 @@
> >> /*
> >> - * VDSO implementation for AArch64 and vector page setup for AArch32.
> >> + * VDSO implementation for AArch64 and for AArch32:
> >> + * AArch64: vDSO implementation contains pages setup and data page update.
> >> + * AArch32: vDSO implementation contains sigreturn and kuser pages setup.
> >> *
> >> * Copyright (C) 2012 ARM Limited
> >> *
> >> @@ -53,61 +55,126 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
> >> /*
> >> * Create and map the vectors page for AArch32 tasks.
> >> */
> >> -static struct page *vectors_page[1] __ro_after_init;
> >> +/*
> >> + * aarch32_vdso_pages:
> >> + * 0 - kuser helpers
> >> + * 1 - sigreturn code
> >> + */
> >> +#define C_VECTORS 0
> >
> > C_KUSER might make more sense, and is consistent with AARCH32_KUSER_BASE.
> >
>
> C_VECTORS seems consistent with the name of the page it refers to.
Ok, then why change AARCH32_VECTORS_BASE? ;)
> >> -int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
> >> +static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
> >> {
> >> - struct mm_struct *mm = current->mm;
> >> - unsigned long addr = AARCH32_VECTORS_BASE;
> >> - static const struct vm_special_mapping spec = {
> >> - .name = "[vectors]",
> >> - .pages = vectors_page,
> >> + void *ret;
> >> +
> >> + /* The kuser helpers must be mapped at the ABI-defined high address */
> >> + ret = _install_special_mapping(mm, AARCH32_KUSER_BASE, PAGE_SIZE,
> >> + VM_READ | VM_EXEC |
> >> + VM_MAYREAD | VM_MAYEXEC,
> >
> > How come you don't need VM_MAYWRITE here...
> >
>
> This is to keep it consistent with what the arm (32 bit) implementation does.
>
> My understanding is that the kuser code is executed in user mode for efficiency
> reasons but it is too close to the kernel to be implemented in user libraries
> and that the kernel can change its internal implementation from version to
> version as far as it guarantees the "interface" (entry points and results).
> Based on this gdb should not need to put a breakpoint inside the kuser helpers code.
Hmm, but couldn't you apply the same reasoning to the sigpage?
[also, talking to Russell, he makes the very good point that you can't CoW
the page containing the vectors because that would give userspace control
over the vectors themselves!]
> And if we consider as well that the fixed address nature of the helpers could be
> used from ROP authors during the creation of exploits probably we want to
> prevent gdb to set a breakpoint there hence the proposed patch does not contain
> VM_MAYWRITE.
I'm not sure I buy the ROP angle... you need to GUP the thing to get the
write to happen. Maybe you could do it with a futex or something, but I'm
also not sure that's really a viable attack.
> I had a look to arm implementation and it seems the it defines the vector page
> as READONLY_EXEC and there is no VM_MAYWRITE in the vm_flags.
>
> I could extend the comment accordingly.
I initially thought that the gate VMA would mean that VM_MAYWRITE was
implicit for GUP, but actually that's handled explicitly in get_gate_page():
/* user gate pages are read-only */
if (gup_flags & FOLL_WRITE)
return -EFAULT;
so yes, I agree with you that this is consistent with 32-bit. What I'm not
sure about is why we need to CoW the sigpage. But I suppose being compatible
with 32-bit is the aim of the game, so this is all moot.
> >> + /*
> >> + * VM_MAYWRITE is required to allow gdb to Copy-on-Write and
> >> + * set breakpoints.
> >> + */
> >> ret = _install_special_mapping(mm, addr, PAGE_SIZE,
> >> - VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC,
> >> - &spec);
> >> + VM_READ | VM_EXEC | VM_MAYREAD |
> >> + VM_MAYWRITE | VM_MAYEXEC,
> >> + &aarch32_vdso_spec[C_SIGPAGE]);
> >
> > ... but you introduce it here?Also, shouldn't this be a separate change
> > so it can be treated as a fix?
>
> This is again to keep it consistent with what the arm implementation does.
>
> Since the separation (vectors/sigpage) has been added in this patch, I am not
> sure on how we can treat this change as a separate patch, at least based on what
> I mentioned above. Could you please explain?
Sorry, I was getting ahead of myself with that. If we need to add
VM_MAYWRITE to the compat kuser helpers (which we could safely do on
64-bit), then we could do it as a fix. However, we don't need to do that
do please ignore my comment above.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-04-12 11:55 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-02 16:27 [PATCH v3 0/4] arm64: compat: Add kuser helpers config option Vincenzo Frascino
2019-04-02 16:27 ` [PATCH v3 1/4] arm64: compat: Alloc separate pages for vectors and sigpage Vincenzo Frascino
2019-04-10 18:10 ` Will Deacon
2019-04-12 11:08 ` Vincenzo Frascino
2019-04-12 11:55 ` Will Deacon [this message]
2019-04-12 13:28 ` Vincenzo Frascino
2019-04-12 13:30 ` Russell King - ARM Linux admin
2019-04-02 16:27 ` [PATCH v3 2/4] arm64: compat: Split kuser32 Vincenzo Frascino
2019-04-02 16:27 ` [PATCH v3 3/4] arm64: compat: Refactor aarch32_alloc_vdso_pages() Vincenzo Frascino
2019-04-02 16:36 ` Catalin Marinas
2019-04-02 16:27 ` [PATCH v3 4/4] arm64: compat: Add KUSER_HELPERS config option Vincenzo Frascino
2019-04-04 10:08 ` Catalin Marinas
2019-04-04 14:07 ` Vincenzo Frascino
2019-04-04 14:51 ` Catalin Marinas
2019-04-04 15:01 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190412115507.GA28260@fuggles.cambridge.arm.com \
--to=will.deacon@arm.com \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=mark.rutland@arm.com \
--cc=vincenzo.frascino@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).