Module Name:    src
Committed By:   maxv
Date:           Sun Apr 12 07:49:58 UTC 2020

Modified Files:
        src/sys/arch/aarch64/aarch64: aarch64_machdep.c cpufunc.c cpuswitch.S
            db_trace.c genassym.cf locore.S vectors.S vm_machdep.c
        src/sys/arch/aarch64/conf: Makefile.aarch64
        src/sys/arch/aarch64/include: armreg.h asm.h cpufunc.h proc.h
        src/sys/arch/arm/conf: files.arm
        src/sys/arch/evbarm/conf: GENERIC64

Log Message:
Add support for Pointer Authentication (PAC).

We use the "pac-ret" option, to sign the return instruction pointer on
function entry, and authenticate it on function exit. This acts as a
mitigation against ROP.

The authentication uses a per-lwp (secret) I-A key stored in the 128bit
APIAKey register and part of the lwp context. During lwp creation, the
kernel generates a random key, and during context switches, it installs
the key of the target lwp on the CPU.

Userland cannot read the APIAKey register directly. However, it can sign
its pointers with it, because the register is architecturally shared
between userland and the kernel. Although part of the CPU design, it is
a bit of an undesired behavior, because it allows to forge valid kernel
pointers from userland. To avoid that, we don't share the key with
userland, and rather switch it in EL0<->EL1 transitions. This means that
when userland executes, a different key is loaded in APIAKey than the one
the kernel uses. For now the userland key is a fixed 128bit zero value.

The DDB stack unwinder is changed to strip the authentication code from
the pointers in lr.

Two problems are known:

 * Currently the idlelwps' keys are not really secret. This is because
   the RNG is not yet available when we spawn these lwps. Not overly
   important, but would be nice to fix with UEFI RNG.
 * The key switching in EL0<->EL1 transitions is not the most optimized
   code on the planet. Instead of checking aarch64_pac_enabled, it would
   be better to hot-patch the code at boot time, but there currently is
   no hot-patch support on aarch64.

Tested on Qemu.


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/aarch64/aarch64/aarch64_machdep.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/aarch64/aarch64/cpufunc.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/aarch64/aarch64/cpuswitch.S
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/aarch64/aarch64/db_trace.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/aarch64/aarch64/genassym.cf
cvs rdiff -u -r1.58 -r1.59 src/sys/arch/aarch64/aarch64/locore.S
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/aarch64/aarch64/vectors.S
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/aarch64/aarch64/vm_machdep.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/aarch64/conf/Makefile.aarch64
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/aarch64/include/armreg.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/include/asm.h
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/aarch64/include/cpufunc.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/aarch64/include/proc.h
cvs rdiff -u -r1.153 -r1.154 src/sys/arch/arm/conf/files.arm
cvs rdiff -u -r1.149 -r1.150 src/sys/arch/evbarm/conf/GENERIC64

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Reply via email to