[00/17] ARMv8.3 pointer authentication support
mbox series

Message ID 20181005084754.20950-1-kristina.martsenko@arm.com
Headers show
Series
  • ARMv8.3 pointer authentication support
Related show

Message

Kristina Martsenko Oct. 5, 2018, 8:47 a.m. UTC
Hi,

This series adds support for the ARMv8.3 pointer authentication
extension. The series contains Mark's original patches to enable pointer
authentication for userspace [1], followed by early RFC patches using
pointer authentication in the kernel.

For now it would make sense to focus on reviewing the userspace pointer
authentication patches, with the in-kernel pointer authentication
patches as support to show that the ABI exposed to userspace (e.g.
APIAKey) does not prevent pointer authentication use in the kernel.

This series is based on v4.19-rc5. The aarch64 bootwrapper [2] does the
necessary EL3 setup.


Extension Overview
==================

The ARMv8.3 pointer authentication extension adds functionality to detect
modification of pointer values, mitigating certain classes of attack such as
stack smashing, and making return oriented programming attacks harder.

The extension introduces the concept of a pointer authentication code (PAC),
which is stored in some upper bits of pointers. Each PAC is derived from the
original pointer, another 64-bit value (e.g. the stack pointer), and a secret
128-bit key.

New instructions are added which can be used to:

* Insert a PAC into a pointer
* Strip a PAC from a pointer
* Authenticate strip a PAC from a pointer

If authentication succeeds, the code is removed, yielding the original pointer.
If authentication fails, bits are set in the pointer such that it is guaranteed
to cause a fault if used.

These instructions can make use of four keys:

* APIAKey (A.K.A. Instruction A key)
* APIBKey (A.K.A. Instruction B key)
* APDAKey (A.K.A. Data A key)
* APDBKey (A.K.A. Data B Key)

A subset of these instruction encodings have been allocated from the HINT
space, and will operate as NOPs on any ARMv8-A parts which do not feature the
extension (or if purposefully disabled by the kernel). Software using only this
subset of the instructions should function correctly on all ARMv8-A parts.

Additionally, instructions are added to authenticate small blocks of memory in
similar fashion, using APGAKey (A.K.A. Generic key).


Userspace pointer authentication
================================

The first part of this series (sent as [PATCH v5]) adds support for
pointer authentication in userspace. This enables userspace return
address protection with GCC 7 and higher.

Changes since v4 [1]:
 - rebase onto v4.19-rc5
 - patch #7: move key init from init_new_context to arch_bprm_mm_init,
   remove unused mm_ctx_ptrauth_dup, add back mm_hooks patch from v3
 - patch #7: add AA64ISAR1.API HWCAP_CAP
 - patch #11: update cpu-feature-registers.txt
 - minor cleanups

I've kept all Reviewed-by/Acked-by/Tested-by tags from v4.

There are a couple of things worth noting:

1) Key support

This series enables the use of instructions using APIAKey, which is
initialised and maintained per-process (shared by all threads). GCC
currently only makes use of APIAKey.

This series does not add support for APIBKey, APDAKey, APDBKey, nor
APGAKey. HINT-space instructions using these keys will currently execute
as NOPs. Support for these keys can be added as users appear.

Note that while we expose the cpuid register (ID_AA64ISAR1_EL1) to
userspace, it only contains one feature for address authentication
(API/APA), so it cannot be used by userspace to tell which keys the
kernel supports. For this the kernel exposes HWCAP bits, one per key
(currently only APIAKey), which must be checked instead.

2) Checkpoint/restore

I have not yet looked at if checkpoint/restore works with applications
using pointer authentication. Presumably we will need to save and
restore the keys a task is using. To restore the keys from userspace, we
may need some way to set the keys for the task, such as through a prctl.

3) Key initialisation in Android

Currently, keys are preserved across fork and reinitialised on exec. If
keys were reinitialised on fork, it would break applications where both
parent and child return from the function that called fork.

This may however be a problem in environments where only fork is used to
start applications, and exec is not used. If I understand correctly, the
Android Zygote process model works like this. This would mean that in
Android, all processes would share the same key. We may therefore need a
mechanism for userspace to request keys to be reinitialised, e.g. a
clone flag, prctl, or trapped access to key registers.

4) KVM guest support

For the time being, this series hides pointer authentication
functionality from KVM guests. Amit Kachhap is currently looking into
supporting pointer authentication in guests.

5) uprobes

Setting uprobes on pointer authentication instructions is not yet
supported, and may cause the application to behave in unexpected ways.


In-kernel pointer authentication
================================

The second part of this series (sent as [RFC]) adds support for building
the kernel with pointer authentication instructions.

This means adding two instructions to every function: one to sign the
return address at the beginning of the function, and one to authenticate
the return address just before returning to it. If authentication fails,
the return will cause an exception to be taken, followed by a
panic/oops. This should help protect the kernel against attacks using
return-oriented programming.

Each task has its own pointer authentication key for use in the kernel,
initialized during fork. On systems without much entropy during early
boot, the earlier keys are unfortunately not unpredictable. Ideally the
kernel should get early randomness from firmware. Currently, this should
be possible on UEFI systems that support EFI_RNG_PROTOCOL (via
LINUX_EFI_RANDOM_SEED_TABLE_GUID). ARMv8.5-A will also add Random Number
instructions that should help with this [3].

The kernel currently uses only APIAKey, and switches it on entry and
exit to userspace. If/when GCC gains support for generating APIBKey
instructions, it may be worth switching to APIBKey if there is a
performance benefit (if userspace only uses APIAKey).

This series is currently intended as an RFC. Some things I haven't yet
looked at include:
  - debug and trace (ftrace, kprobes, __builtin_return_address(n),
    kdump, ...)
  - interaction with stack protector
  - suspend/resume
  - compiler without ptrauth support
  - separate kconfig option?

Feedback and comments are welcome.

Thanks,
Kristina

[1] https://lore.kernel.org/lkml/20180503132031.25705-1-mark.rutland@arm.com/
[2] git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git
[3] https://community.arm.com/processors/b/blog/posts/arm-a-profile-architecture-2018-developments-armv85a


Kristina Martsenko (3):
  arm64: enable ptrauth earlier
  arm64: initialize and switch ptrauth kernel keys
  arm64: compile the kernel with ptrauth -msign-return-address

Mark Rutland (14):
  arm64: add pointer authentication register bits
  arm64/kvm: consistently handle host HCR_EL2 flags
  arm64/kvm: hide ptrauth from guests
  arm64: Don't trap host pointer auth use to EL2
  arm64/cpufeature: detect pointer authentication
  asm-generic: mm_hooks: allow hooks to be overridden individually
  arm64: add basic pointer authentication support
  arm64: expose user PAC bit positions via ptrace
  arm64: perf: strip PAC when unwinding userspace
  arm64: enable pointer authentication
  arm64: docs: document pointer authentication
  arm64: move ptrauth keys to thread_info
  arm64: install user ptrauth keys at kernel exit time
  arm64: unwind: strip PAC from kernel addresses

 Documentation/arm64/booting.txt                |   8 ++
 Documentation/arm64/cpu-feature-registers.txt  |   4 +
 Documentation/arm64/elf_hwcaps.txt             |   5 ++
 Documentation/arm64/pointer-authentication.txt |  84 ++++++++++++++++++++
 arch/arm64/Kconfig                             |  23 ++++++
 arch/arm64/Makefile                            |   4 +
 arch/arm64/include/asm/cpucaps.h               |   5 +-
 arch/arm64/include/asm/cpufeature.h            |   9 +++
 arch/arm64/include/asm/esr.h                   |   3 +-
 arch/arm64/include/asm/kvm_arm.h               |   3 +
 arch/arm64/include/asm/mmu_context.h           |   3 +-
 arch/arm64/include/asm/pointer_auth.h          | 103 +++++++++++++++++++++++++
 arch/arm64/include/asm/ptrauth-asm.h           |  39 ++++++++++
 arch/arm64/include/asm/sysreg.h                |  30 +++++++
 arch/arm64/include/asm/thread_info.h           |   5 ++
 arch/arm64/include/uapi/asm/hwcap.h            |   1 +
 arch/arm64/include/uapi/asm/ptrace.h           |   7 ++
 arch/arm64/kernel/asm-offsets.c                |   8 ++
 arch/arm64/kernel/cpufeature.c                 |  51 ++++++++++++
 arch/arm64/kernel/cpuinfo.c                    |   1 +
 arch/arm64/kernel/entry.S                      |  13 +++-
 arch/arm64/kernel/head.S                       |   5 +-
 arch/arm64/kernel/perf_callchain.c             |   6 +-
 arch/arm64/kernel/process.c                    |   6 ++
 arch/arm64/kernel/ptrace.c                     |  38 +++++++++
 arch/arm64/kernel/smp.c                        |  10 ++-
 arch/arm64/kernel/stacktrace.c                 |   3 +
 arch/arm64/kvm/handle_exit.c                   |  18 +++++
 arch/arm64/kvm/hyp/switch.c                    |   2 +-
 arch/arm64/kvm/sys_regs.c                      |   8 ++
 include/asm-generic/mm_hooks.h                 |  11 +++
 include/uapi/linux/elf.h                       |   1 +
 32 files changed, 506 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/arm64/pointer-authentication.txt
 create mode 100644 arch/arm64/include/asm/pointer_auth.h
 create mode 100644 arch/arm64/include/asm/ptrauth-asm.h

Comments

Ramana Radhakrishnan Oct. 5, 2018, 9:01 a.m. UTC | #1
On 05/10/2018 09:47, Kristina Martsenko wrote:
> Compile all functions with two ptrauth instructions: paciasp in the
> prologue to sign the return address, and autiasp in the epilogue to
> authenticate the return address. This should help protect the kernel
> against attacks using return-oriented programming.
> 
> CONFIG_ARM64_PTR_AUTH enables pointer auth for both userspace and the
> kernel.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
> ---
>   arch/arm64/Makefile | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 106039d25e2f..dbcd43ea99d8 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -56,6 +56,10 @@ KBUILD_AFLAGS	+= $(lseinstr) $(brokengasinst)
>   KBUILD_CFLAGS	+= $(call cc-option,-mabi=lp64)
>   KBUILD_AFLAGS	+= $(call cc-option,-mabi=lp64)
>   
> +ifeq ($(CONFIG_ARM64_PTR_AUTH),y)
> +KBUILD_CFLAGS	+= -msign-return-address=all

Glad to see this being done and being proposed for mainline.

I can see why you would prefer this though have you guys experimented at 
all with -msign-return-address=non-leaf as well ?

Orthogonally and just fair warning - the command lines for this are also 
being revised to provide ROP and JOP protection using BTI from v8.5-a 
during the GCC-9 timeframe but I suspect that's a different option.

regards
Ramana

Reviewed-by: Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
Kristina Martsenko Oct. 11, 2018, 2 p.m. UTC | #2
On 05/10/2018 10:01, Ramana Radhakrishnan wrote:
> On 05/10/2018 09:47, Kristina Martsenko wrote:
>> Compile all functions with two ptrauth instructions: paciasp in the
>> prologue to sign the return address, and autiasp in the epilogue to
>> authenticate the return address. This should help protect the kernel
>> against attacks using return-oriented programming.
>>
>> CONFIG_ARM64_PTR_AUTH enables pointer auth for both userspace and the
>> kernel.
>>
>> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
>> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
>> ---
>>   arch/arm64/Makefile | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>> index 106039d25e2f..dbcd43ea99d8 100644
>> --- a/arch/arm64/Makefile
>> +++ b/arch/arm64/Makefile
>> @@ -56,6 +56,10 @@ KBUILD_AFLAGS    += $(lseinstr) $(brokengasinst)
>>   KBUILD_CFLAGS    += $(call cc-option,-mabi=lp64)
>>   KBUILD_AFLAGS    += $(call cc-option,-mabi=lp64)
>>   +ifeq ($(CONFIG_ARM64_PTR_AUTH),y)
>> +KBUILD_CFLAGS    += -msign-return-address=all
> 
> Glad to see this being done and being proposed for mainline.
> 
> I can see why you would prefer this though have you guys experimented at
> all with -msign-return-address=non-leaf as well ?

I've tried non-leaf and it works too. I'd be fine with switching to it,
I'm not sure which would be better for the kernel.

What kind of experiments did you have in mind? If I understand
correctly, then compared to non-leaf, "all" additionally protects leaf
functions that write to the stack. I don't know how many of those there
are in the kernel (or will be in the future). I also don't know the
additional performance impact of "all", as I don't think we have any
v8.3 hardware to test on yet. There is a minor code size impact (0.36%
on the current kernel), but I'm not sure how much that matters.

> Orthogonally and just fair warning - the command lines for this are also
> being revised to provide ROP and JOP protection using BTI from v8.5-a
> during the GCC-9 timeframe but I suspect that's a different option.

Thanks. I expect it will be a separate Kconfig option to build the
kernel with BTI and pointer auth, yes.

> Reviewed-by: Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>

Thanks!

Kristina
Kees Cook Oct. 15, 2018, 10:42 p.m. UTC | #3
On Fri, Oct 5, 2018 at 1:47 AM, Kristina Martsenko
<kristina.martsenko@arm.com> wrote:
> This series adds support for the ARMv8.3 pointer authentication
> extension. The series contains Mark's original patches to enable pointer
> authentication for userspace [1], followed by early RFC patches using
> pointer authentication in the kernel.

It wasn't obvious to me where the PAC mismatch exceptions will be
caught. I'm mainly curious to compare the PAC exception handling to
the existing stack-protector panic(). Can you point me to which
routines manage that? (Perhaps I just missed it in the series...)

Thanks for the series! I'm quite excited for ARMv8.3 hardware. :)

-Kees
Will Deacon Oct. 19, 2018, 12:36 p.m. UTC | #4
On Fri, Oct 05, 2018 at 09:47:37AM +0100, Kristina Martsenko wrote:
> 1) Key support
> 
> This series enables the use of instructions using APIAKey, which is
> initialised and maintained per-process (shared by all threads). GCC
> currently only makes use of APIAKey.
> 
> This series does not add support for APIBKey, APDAKey, APDBKey, nor
> APGAKey. HINT-space instructions using these keys will currently execute
> as NOPs. Support for these keys can be added as users appear.
> 
> Note that while we expose the cpuid register (ID_AA64ISAR1_EL1) to
> userspace, it only contains one feature for address authentication
> (API/APA), so it cannot be used by userspace to tell which keys the
> kernel supports. For this the kernel exposes HWCAP bits, one per key
> (currently only APIAKey), which must be checked instead.

Given that the architecture doesn't provide an identification mechanism
for the case where only one of the keys is available, I would much prefer
that we expose both of the keys to userspace. Is the only downside of
that a possible exception entry overhead if the kernel wants to use pointer
authentication as well?

Having an initial implementation where the B key operations act as NOPs
isn't ideal if we want to support future users -- chances are they'll
be put off because deployed kernels don't give them whatever security
guarantees they require. It's a bit of a chicken-and-egg problem, so
unless we have good reasons to keep the B key hidden, I think we should
be exposing it from the start.

Will
Ramana Radhakrishnan Oct. 23, 2018, 8:39 a.m. UTC | #5
On 19/10/2018 13:36, Will Deacon wrote:
> On Fri, Oct 05, 2018 at 09:47:37AM +0100, Kristina Martsenko wrote:
>> 1) Key support
>>
>> This series enables the use of instructions using APIAKey, which is
>> initialised and maintained per-process (shared by all threads). GCC
>> currently only makes use of APIAKey.
>>
>> This series does not add support for APIBKey, APDAKey, APDBKey, nor
>> APGAKey. HINT-space instructions using these keys will currently execute
>> as NOPs. Support for these keys can be added as users appear.
>>
>> Note that while we expose the cpuid register (ID_AA64ISAR1_EL1) to
>> userspace, it only contains one feature for address authentication
>> (API/APA), so it cannot be used by userspace to tell which keys the
>> kernel supports. For this the kernel exposes HWCAP bits, one per key
>> (currently only APIAKey), which must be checked instead.
> 
> Given that the architecture doesn't provide an identification mechanism
> for the case where only one of the keys is available, I would much prefer
> that we expose both of the keys to userspace. Is the only downside of
> that a possible exception entry overhead if the kernel wants to use pointer
> authentication as well?
> 
> Having an initial implementation where the B key operations act as NOPs
> isn't ideal if we want to support future users -- chances are they'll
> be put off because deployed kernels don't give them whatever security
> guarantees they require. It's a bit of a chicken-and-egg problem, so
> unless we have good reasons to keep the B key hidden, I think we should
> be exposing it from the start.

There are patches in flight to get B key signing support in for GCC 9  - 
so exposing this to user space will be good.

Ramana

> 
> Will
>
Kristina Martsenko Nov. 13, 2018, 4:17 p.m. UTC | #6
(Sorry for the really late response!)

On 15/10/2018 23:42, Kees Cook wrote:
> On Fri, Oct 5, 2018 at 1:47 AM, Kristina Martsenko
> <kristina.martsenko@arm.com> wrote:
>> This series adds support for the ARMv8.3 pointer authentication
>> extension. The series contains Mark's original patches to enable pointer
>> authentication for userspace [1], followed by early RFC patches using
>> pointer authentication in the kernel.
> 
> It wasn't obvious to me where the PAC mismatch exceptions will be
> caught. I'm mainly curious to compare the PAC exception handling to
> the existing stack-protector panic(). Can you point me to which
> routines manage that? (Perhaps I just missed it in the series...)

When the PAC authentication fails, it doesn't actually generate an
exception, it just flips a bit in the high-order bits of the pointer,
making the pointer invalid. Then when the pointer is dereferenced (e.g.
as a function return address), it generates the usual type of exception
for an invalid address.

So when a function return fails in user mode, the exception is handled
in __do_user_fault and a forced SIGSEGV is delivered to the task. When a
function return fails in kernel mode, the exception is handled in
__do_kernel_fault and the task is killed.

This is different from stack protector as we don't panic the kernel, we
just kill the task. It would be difficult to panic as we don't have a
reliable way of knowing that the exception was caused by a PAC
authentication failure (we just have an invalid pointer with a specific
bit flipped). We also don't print out any PAC-related warning.

Thanks,
Kristina
Kees Cook Nov. 13, 2018, 11:09 p.m. UTC | #7
On Tue, Nov 13, 2018 at 10:17 AM, Kristina Martsenko
<kristina.martsenko@arm.com> wrote:
> When the PAC authentication fails, it doesn't actually generate an
> exception, it just flips a bit in the high-order bits of the pointer,
> making the pointer invalid. Then when the pointer is dereferenced (e.g.
> as a function return address), it generates the usual type of exception
> for an invalid address.

Ah! Okay, thanks. I missed that detail. :)

What area of memory ends up being addressable with such bit flips?
(i.e. is the kernel making sure nothing executable ends up there?)

> So when a function return fails in user mode, the exception is handled
> in __do_user_fault and a forced SIGSEGV is delivered to the task. When a
> function return fails in kernel mode, the exception is handled in
> __do_kernel_fault and the task is killed.
>
> This is different from stack protector as we don't panic the kernel, we
> just kill the task. It would be difficult to panic as we don't have a
> reliable way of knowing that the exception was caused by a PAC
> authentication failure (we just have an invalid pointer with a specific
> bit flipped). We also don't print out any PAC-related warning.

There are other "guesses" in __do_kernel_fault(), I think? Could a
"PAC mismatch?" warning be included in the Oops if execution fails in
the address range that PAC failures would resolve into?

-Kees
Kristina Martsenko Nov. 14, 2018, 3:54 p.m. UTC | #8
On 13/11/2018 23:09, Kees Cook wrote:
> On Tue, Nov 13, 2018 at 10:17 AM, Kristina Martsenko
> <kristina.martsenko@arm.com> wrote:
>> When the PAC authentication fails, it doesn't actually generate an
>> exception, it just flips a bit in the high-order bits of the pointer,
>> making the pointer invalid. Then when the pointer is dereferenced (e.g.
>> as a function return address), it generates the usual type of exception
>> for an invalid address.
> 
> Ah! Okay, thanks. I missed that detail. :)
> 
> What area of memory ends up being addressable with such bit flips?
> (i.e. is the kernel making sure nothing executable ends up there?)

The address will be in between the user and kernel address ranges, so
it's guaranteed to be invalid and not address any memory.

Specifically, assuming a 48-bit VA configuration, user addresses must
have bits [55:48] clear and kernel addresses must have bits [63:48] set.
When authentication fails it will set two bits in those ranges to "10"
or "01", ensuring that the address is no longer a valid user or kernel
address.

>> So when a function return fails in user mode, the exception is handled
>> in __do_user_fault and a forced SIGSEGV is delivered to the task. When a
>> function return fails in kernel mode, the exception is handled in
>> __do_kernel_fault and the task is killed.
>>
>> This is different from stack protector as we don't panic the kernel, we
>> just kill the task. It would be difficult to panic as we don't have a
>> reliable way of knowing that the exception was caused by a PAC
>> authentication failure (we just have an invalid pointer with a specific
>> bit flipped). We also don't print out any PAC-related warning.
> 
> There are other "guesses" in __do_kernel_fault(), I think? Could a
> "PAC mismatch?" warning be included in the Oops if execution fails in
> the address range that PAC failures would resolve into?

Sounds reasonable to me, I'll add a warning.

Thanks,
Kristina
Mark Rutland Nov. 14, 2018, 9:47 p.m. UTC | #9
On Tue, Nov 13, 2018 at 05:09:00PM -0600, Kees Cook wrote:
> On Tue, Nov 13, 2018 at 10:17 AM, Kristina Martsenko
> <kristina.martsenko@arm.com> wrote:
> > When the PAC authentication fails, it doesn't actually generate an
> > exception, it just flips a bit in the high-order bits of the pointer,
> > making the pointer invalid. Then when the pointer is dereferenced (e.g.
> > as a function return address), it generates the usual type of exception
> > for an invalid address.
> 
> Ah! Okay, thanks. I missed that detail. :)
> 
> What area of memory ends up being addressable with such bit flips?
> (i.e. is the kernel making sure nothing executable ends up there?)
> 
> > So when a function return fails in user mode, the exception is handled
> > in __do_user_fault and a forced SIGSEGV is delivered to the task. When a
> > function return fails in kernel mode, the exception is handled in
> > __do_kernel_fault and the task is killed.
> >
> > This is different from stack protector as we don't panic the kernel, we
> > just kill the task. It would be difficult to panic as we don't have a
> > reliable way of knowing that the exception was caused by a PAC
> > authentication failure (we just have an invalid pointer with a specific
> > bit flipped). We also don't print out any PAC-related warning.
> 
> There are other "guesses" in __do_kernel_fault(), I think? Could a
> "PAC mismatch?" warning be included in the Oops if execution fails in
> the address range that PAC failures would resolve into?

I'd personally prefer that we didn't try to guess if a fault is due to a failed
AUT*, even for logging.

Presently, it's not possible to distinguish between a fault resulting from a
failed AUT* and a fault which happens to have hte same bits/clear, so there are
false positives. The architecture may also change the precise details of the
faulting address, and we'd have false negatives in that case.

Given that, I think suggesting that a fault is due to a failed AUT* is liable
to make things more confusing.

Thanks,
Mark.
Kees Cook Nov. 14, 2018, 10:48 p.m. UTC | #10
On Wed, Nov 14, 2018 at 3:47 PM, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Nov 13, 2018 at 05:09:00PM -0600, Kees Cook wrote:
>> On Tue, Nov 13, 2018 at 10:17 AM, Kristina Martsenko
>> <kristina.martsenko@arm.com> wrote:
>> > When the PAC authentication fails, it doesn't actually generate an
>> > exception, it just flips a bit in the high-order bits of the pointer,
>> > making the pointer invalid. Then when the pointer is dereferenced (e.g.
>> > as a function return address), it generates the usual type of exception
>> > for an invalid address.
>>
>> Ah! Okay, thanks. I missed that detail. :)
>>
>> What area of memory ends up being addressable with such bit flips?
>> (i.e. is the kernel making sure nothing executable ends up there?)
>>
>> > So when a function return fails in user mode, the exception is handled
>> > in __do_user_fault and a forced SIGSEGV is delivered to the task. When a
>> > function return fails in kernel mode, the exception is handled in
>> > __do_kernel_fault and the task is killed.
>> >
>> > This is different from stack protector as we don't panic the kernel, we
>> > just kill the task. It would be difficult to panic as we don't have a
>> > reliable way of knowing that the exception was caused by a PAC
>> > authentication failure (we just have an invalid pointer with a specific
>> > bit flipped). We also don't print out any PAC-related warning.
>>
>> There are other "guesses" in __do_kernel_fault(), I think? Could a
>> "PAC mismatch?" warning be included in the Oops if execution fails in
>> the address range that PAC failures would resolve into?
>
> I'd personally prefer that we didn't try to guess if a fault is due to a failed
> AUT*, even for logging.
>
> Presently, it's not possible to distinguish between a fault resulting from a
> failed AUT* and a fault which happens to have hte same bits/clear, so there are
> false positives. The architecture may also change the precise details of the
> faulting address, and we'd have false negatives in that case.
>
> Given that, I think suggesting that a fault is due to a failed AUT* is liable
> to make things more confusing.

Okay, no worries. It should be pretty clear from the back trace anyway. :)

As long as there isn't any way for the pointer bit flips to result in
an addressable range, I'm happy. :)

-Kees