mbox series

[v8,00/11] arm64: Branch Target Identification support

Message ID 20200227174417.23722-1-broonie@kernel.org (mailing list archive)
Headers show
Series arm64: Branch Target Identification support | expand

Message

Mark Brown Feb. 27, 2020, 5:44 p.m. UTC
This patch series implements support for ARMv8.5-A Branch Target
Identification (BTI), which is a control flow integrity protection
feature introduced as part of the ARMv8.5-A extensions.

Changes:

v8:
 - Remove a redundant IS_ENABLED(CONFIG_ARM64_BTI) check.
v7:
 - Rebase onto v5.6-rc3.
 - Move comment about keeping NT_GNU_PROPERTY_TYPE_0 internal into first
   patch.
 - Add an explicit check for system_supports_bti() when parsing BTI ELF
   property for improved robustness.
v6:
 - Rebase onto v5.6-rc1.
 - Fix typos s/BYTPE/BTYPE/ in commit log for "arm64: BTI: Decode BYTPE
   bits when printing PSTATE".
v5:
 - Changed a bunch of -EIO to -ENOEXEC in the ELF parsing code.
 - Move PSR_BTYPE defines to UAPI.
 - Use compat_user_mode() rather than open coding.
 - Fix a typo s/BYTPE/BTYPE/ in syscall.c
v4:
 - Dropped patch fixing existing documentation as it has already been merged.
 - Convert WARN_ON() to WARN_ON_ONCE() in "ELF: Add ELF program property
   parsing support".
 - Added display of guarded pages to ptdump.
 - Updated for conversion of exception handling from assembler to C.

Notes:

 * GCC 9 can compile backwards-compatible BTI-enabled code with
   -mbranch-protection=bti or -mbranch-protection=standard.

 * Binutils trunk supports the new ELF note, but this wasn't in a release
   the last time I posted this series.  (The situation _might_ have changed
   in the meantime...)

   Creation of a BTI-enabled binary requires _everything_ linked in to
   be BTI-enabled.  For now ld --force-bti can be used to override this,
   but some things may break until the required C library support is in
   place.

   There is no straightforward way to mark a .s file as BTI-enabled:
   scraping the output from gcc -S works as a quick hack for now.

   readelf -n can be used to examing the program properties in an ELF
   file.

 * Runtime mmap() and mprotect() can be used to enable BTI on a
   page-by-page basis using the new PROT_BTI, but the code in the
   affected pages still needs to be written or compiled to contain the
   appopriate BTI landing pads.

Dave Martin (10):
  ELF: UAPI and Kconfig additions for ELF program properties
  ELF: Add ELF program property parsing support
  arm64: Basic Branch Target Identification support
  elf: Allow arch to tweak initial mmap prot flags
  arm64: elf: Enable BTI at exec based on ELF program properties
  arm64: BTI: Decode BYTPE bits when printing PSTATE
  arm64: unify native/compat instruction skipping
  arm64: traps: Shuffle code to eliminate forward declarations
  arm64: BTI: Reset BTYPE when skipping emulated instructions
  KVM: arm64: BTI: Reset BTYPE when skipping emulated instructions

Mark Brown (1):
  arm64: mm: Display guarded pages in ptdump

 Documentation/arm64/cpu-feature-registers.rst |   2 +
 Documentation/arm64/elf_hwcaps.rst            |   5 +
 arch/arm64/Kconfig                            |  25 +++
 arch/arm64/include/asm/cpucaps.h              |   3 +-
 arch/arm64/include/asm/cpufeature.h           |   6 +
 arch/arm64/include/asm/elf.h                  |  50 ++++++
 arch/arm64/include/asm/esr.h                  |   2 +-
 arch/arm64/include/asm/exception.h            |   1 +
 arch/arm64/include/asm/hwcap.h                |   1 +
 arch/arm64/include/asm/kvm_emulate.h          |   6 +-
 arch/arm64/include/asm/mman.h                 |  37 +++++
 arch/arm64/include/asm/pgtable-hwdef.h        |   1 +
 arch/arm64/include/asm/pgtable.h              |   2 +-
 arch/arm64/include/asm/ptrace.h               |   1 +
 arch/arm64/include/asm/sysreg.h               |   4 +
 arch/arm64/include/uapi/asm/hwcap.h           |   1 +
 arch/arm64/include/uapi/asm/mman.h            |   9 ++
 arch/arm64/include/uapi/asm/ptrace.h          |   9 ++
 arch/arm64/kernel/cpufeature.c                |  33 ++++
 arch/arm64/kernel/cpuinfo.c                   |   1 +
 arch/arm64/kernel/entry-common.c              |  11 ++
 arch/arm64/kernel/process.c                   |  36 ++++-
 arch/arm64/kernel/ptrace.c                    |   2 +-
 arch/arm64/kernel/signal.c                    |  16 ++
 arch/arm64/kernel/syscall.c                   |  18 +++
 arch/arm64/kernel/traps.c                     | 127 +++++++--------
 arch/arm64/mm/dump.c                          |   5 +
 fs/Kconfig.binfmt                             |   6 +
 fs/binfmt_elf.c                               | 145 +++++++++++++++++-
 fs/compat_binfmt_elf.c                        |   4 +
 include/linux/elf.h                           |  43 ++++++
 include/linux/mm.h                            |   3 +
 include/uapi/linux/elf.h                      |  11 ++
 33 files changed, 551 insertions(+), 75 deletions(-)
 create mode 100644 arch/arm64/include/asm/mman.h
 create mode 100644 arch/arm64/include/uapi/asm/mman.h

Comments

Richard Henderson Feb. 28, 2020, 1:35 a.m. UTC | #1
On 2/27/20 9:44 AM, Mark Brown wrote:
>  * Binutils trunk supports the new ELF note, but this wasn't in a release
>    the last time I posted this series.  (The situation _might_ have changed
>    in the meantime...)

I believe this support is in binutils 2.32.


r~
Catalin Marinas March 6, 2020, 10:21 a.m. UTC | #2
On Thu, Feb 27, 2020 at 05:44:06PM +0000, Mark Brown wrote:
> Dave Martin (10):
>   ELF: UAPI and Kconfig additions for ELF program properties
>   ELF: Add ELF program property parsing support
>   arm64: Basic Branch Target Identification support
>   elf: Allow arch to tweak initial mmap prot flags

Al, are you ok for patches 1, 2 and 4 in this series to be merged via
the arm64 tree? The full series is here:

https://lore.kernel.org/linux-arm-kernel/20200227174417.23722-1-broonie@kernel.org/

Thanks.
Catalin Marinas March 6, 2020, 10:27 a.m. UTC | #3
On Thu, Feb 27, 2020 at 05:44:06PM +0000, Mark Brown wrote:
> This patch series implements support for ARMv8.5-A Branch Target
> Identification (BTI), which is a control flow integrity protection
> feature introduced as part of the ARMv8.5-A extensions.

Does this series affect uprobes in any way? I.e. can you probe a landing
pad?
Mark Brown March 9, 2020, 9:05 p.m. UTC | #4
On Fri, Mar 06, 2020 at 10:27:29AM +0000, Catalin Marinas wrote:
> On Thu, Feb 27, 2020 at 05:44:06PM +0000, Mark Brown wrote:

> > This patch series implements support for ARMv8.5-A Branch Target
> > Identification (BTI), which is a control flow integrity protection
> > feature introduced as part of the ARMv8.5-A extensions.

> Does this series affect uprobes in any way? I.e. can you probe a landing
> pad?

You can't probe a landing pad, uprobes on landing pads will be silently
ignored so the program isn't disrupted, you just don't get the expected
trace from those uprobes.  This isn't new with the BTI support since
the landing pads are generally pointer auth instructions, these already
can't be probed regardless of what's going on with this series.  It's
already on the list to get sorted.
Mark Brown March 10, 2020, 12:42 p.m. UTC | #5
On Mon, Mar 09, 2020 at 09:05:05PM +0000, Mark Brown wrote:
> On Fri, Mar 06, 2020 at 10:27:29AM +0000, Catalin Marinas wrote:

> > Does this series affect uprobes in any way? I.e. can you probe a landing
> > pad?

> You can't probe a landing pad, uprobes on landing pads will be silently
> ignored so the program isn't disrupted, you just don't get the expected
> trace from those uprobes.  This isn't new with the BTI support since
> the landing pads are generally pointer auth instructions, these already
> can't be probed regardless of what's going on with this series.  It's
> already on the list to get sorted.

Sorry, I realized thanks to Amit's off-list prompting that I was testing
that I was verifying with the wrong kernel binary here (user error since
it took me a while to sort out uprobes) so this isn't quite right - you
can probe the landing pads with or without this series.
Catalin Marinas March 11, 2020, 4:28 p.m. UTC | #6
On Tue, Mar 10, 2020 at 12:42:26PM +0000, Mark Brown wrote:
> On Mon, Mar 09, 2020 at 09:05:05PM +0000, Mark Brown wrote:
> > On Fri, Mar 06, 2020 at 10:27:29AM +0000, Catalin Marinas wrote:
> 
> > > Does this series affect uprobes in any way? I.e. can you probe a landing
> > > pad?
> 
> > You can't probe a landing pad, uprobes on landing pads will be silently
> > ignored so the program isn't disrupted, you just don't get the expected
> > trace from those uprobes.  This isn't new with the BTI support since
> > the landing pads are generally pointer auth instructions, these already
> > can't be probed regardless of what's going on with this series.  It's
> > already on the list to get sorted.
> 
> Sorry, I realized thanks to Amit's off-list prompting that I was testing
> that I was verifying with the wrong kernel binary here (user error since
> it took me a while to sort out uprobes) so this isn't quite right - you
> can probe the landing pads with or without this series.

Can we not change aarch64_insn_is_nop() to actually return true only for
NOP and ignore everything else in the hint space? We tend to re-use the
hint instructions for new things in the architecture, so I'd rather
white-list what we know we can safely probe than black-listing only some
of the hint instructions.

I haven't assessed the effort of doing the above (probably not a lot)
but as a short-term workaround we could add the BTI and PAC hint
instructions to the aarch64_insn_is_nop() (though my preferred option is
the white-list one).
Mark Brown March 11, 2020, 5:25 p.m. UTC | #7
On Wed, Mar 11, 2020 at 04:28:58PM +0000, Catalin Marinas wrote:
> On Tue, Mar 10, 2020 at 12:42:26PM +0000, Mark Brown wrote:

> > Sorry, I realized thanks to Amit's off-list prompting that I was testing
> > that I was verifying with the wrong kernel binary here (user error since
> > it took me a while to sort out uprobes) so this isn't quite right - you
> > can probe the landing pads with or without this series.

> Can we not change aarch64_insn_is_nop() to actually return true only for
> NOP and ignore everything else in the hint space? We tend to re-use the
> hint instructions for new things in the architecture, so I'd rather
> white-list what we know we can safely probe than black-listing only some
> of the hint instructions.

That's literally the patch I am sitting on which made the difference
with the testing on the wrong binary.

> I haven't assessed the effort of doing the above (probably not a lot)
> but as a short-term workaround we could add the BTI and PAC hint
> instructions to the aarch64_insn_is_nop() (though my preferred option is
> the white-list one).

The only thing I've seen in testing with just NOPs whitelisted is an
inability to probe the PAC instructions which isn't the best user
experience, especially since the effect is that the probes get silently
ignored.  This isn't extensive userspace testing though.  Adding
whitelisting of the BTI and PAC hints would definitely be a safer as a
first step though.  I can post either version?
Mark Brown March 11, 2020, 7:15 p.m. UTC | #8
On Thu, Feb 27, 2020 at 05:35:39PM -0800, Richard Henderson wrote:
> On 2/27/20 9:44 AM, Mark Brown wrote:
> >  * Binutils trunk supports the new ELF note, but this wasn't in a release
> >    the last time I posted this series.  (The situation _might_ have changed
> >    in the meantime...)

> I believe this support is in binutils 2.32.

It looks like it's actually 2.33 but either way it's in a release,
thanks for prompting me to check.  I've updated this for v9.
Catalin Marinas March 12, 2020, 6:42 p.m. UTC | #9
On Wed, Mar 11, 2020 at 05:25:56PM +0000, Mark Brown wrote:
> On Wed, Mar 11, 2020 at 04:28:58PM +0000, Catalin Marinas wrote:
> > On Tue, Mar 10, 2020 at 12:42:26PM +0000, Mark Brown wrote:
> > > Sorry, I realized thanks to Amit's off-list prompting that I was testing
> > > that I was verifying with the wrong kernel binary here (user error since
> > > it took me a while to sort out uprobes) so this isn't quite right - you
> > > can probe the landing pads with or without this series.
> 
> > Can we not change aarch64_insn_is_nop() to actually return true only for
> > NOP and ignore everything else in the hint space? We tend to re-use the
> > hint instructions for new things in the architecture, so I'd rather
> > white-list what we know we can safely probe than black-listing only some
> > of the hint instructions.
[...]
> > I haven't assessed the effort of doing the above (probably not a lot)
> > but as a short-term workaround we could add the BTI and PAC hint
> > instructions to the aarch64_insn_is_nop() (though my preferred option is
> > the white-list one).
> 
> The only thing I've seen in testing with just NOPs whitelisted is an
> inability to probe the PAC instructions which isn't the best user
> experience, especially since the effect is that the probes get silently
> ignored. This isn't extensive userspace testing though.  Adding
> whitelisting of the BTI and PAC hints would definitely be a safer as a
> first step though.  I can post either version?

I thought BTI and PAC are already whitelisted in mainline as they fall
into the hint space (by whitelisting I mean you can probe them).

I'm trying to understand how the BTI patches affect the current uprobes
support and what is needed. Executing BTI or PCI?SP out of line should
be fine as they don't generate a BTI exception (the BRK doesn't either,
just the normal debug exception).

I think (it needs checking) that BRK preserves the PSTATE.BTYPE in SPSR.
If we probe an instruction in a guarded page and then we single-step it
in a non-guarded page, we'll miss a potential BTI fault. Is this an
issue?

If we are to keep the BTI faulting behaviour, we'd need an additional
xol page, guarded, and to find a way to report the original probed
address of the fault rather than the xol page.

So, IIUC, we don't have an issue with the actual BTI or PACI?SP
instructions but rather the other instructions that would not fault with
the BTI support. While we should try to address this, I think the
important bit now is not to break the existing uprobes support when
running a binary with BTI enabled.

Have I missed anything?
Mark Brown March 13, 2020, 12:59 p.m. UTC | #10
On Thu, Mar 12, 2020 at 06:42:11PM +0000, Catalin Marinas wrote:
> On Wed, Mar 11, 2020 at 05:25:56PM +0000, Mark Brown wrote:
> > On Wed, Mar 11, 2020 at 04:28:58PM +0000, Catalin Marinas wrote:

> > > Can we not change aarch64_insn_is_nop() to actually return true only for
> > > NOP and ignore everything else in the hint space? We tend to re-use the

> > ignored. This isn't extensive userspace testing though.  Adding
> > whitelisting of the BTI and PAC hints would definitely be a safer as a
> > first step though.  I can post either version?

> I thought BTI and PAC are already whitelisted in mainline as they fall
> into the hint space (by whitelisting I mean you can probe them).

This was in the context of your comment above about modifying
aarch64_insn_is_nop() - if we do that and nothing else then we'd remove
the current whitelisting.

> I'm trying to understand how the BTI patches affect the current uprobes
> support and what is needed. Executing BTI or PCI?SP out of line should
> be fine as they don't generate a BTI exception (the BRK doesn't either,
> just the normal debug exception).

Right.

> I think (it needs checking) that BRK preserves the PSTATE.BTYPE in SPSR.

Yes, Exception_SoftwareBreakpoint preserves PSTATE.BTYPE.

> If we probe an instruction in a guarded page and then we single-step it
> in a non-guarded page, we'll miss a potential BTI fault. Is this an
> issue?

Obviously the main thing here is that if we miss faults then that's
potentially opening something that could be used as part of an exploit
chain.  I'm not aware of any sensible applications that would generate
the exceptions in normal operation.

> If we are to keep the BTI faulting behaviour, we'd need an additional
> xol page, guarded, and to find a way to report the original probed
> address of the fault rather than the xol page.

Yes, or just accept the inaccurate fault address which isn't good but
might be the least worst thing if there's issues with reporting the
original address.

> So, IIUC, we don't have an issue with the actual BTI or PACI?SP
> instructions but rather the other instructions that would not fault with
> the BTI support. While we should try to address this, I think the
> important bit now is not to break the existing uprobes support when
> running a binary with BTI enabled.

I think so, and as far as my ability to tell goes the worst consequence
would be missing exceptions like you say.  That's not great but it's at
least an extra hoop people have to jump through.