1/* 2 * Copyright (c) 2018 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <arm64/asm.h> 30#include <pexpert/arm64/board_config.h> 31 32 33#if CONFIG_SPTM 34 .text 35 .align 2 36 .globl EXT(arm64_panic_lockdown_test_load) 37LEXT(arm64_panic_lockdown_test_load) 38 ARM64_PROLOG 39 ldr x0, [x0] 40 ret 41 42 .globl EXT(arm64_panic_lockdown_test_gdbtrap) 43LEXT(arm64_panic_lockdown_test_gdbtrap) 44 ARM64_PROLOG 45 .long 0xe7ffdefe 46 ret 47 48#if __has_feature(ptrauth_calls) 49 .globl EXT(arm64_panic_lockdown_test_pac_brk_c470) 50LEXT(arm64_panic_lockdown_test_pac_brk_c470) 51 ARM64_PROLOG 52 brk 0xC470 53 ret 54 55 .globl EXT(arm64_panic_lockdown_test_pac_brk_c471) 56LEXT(arm64_panic_lockdown_test_pac_brk_c471) 57 ARM64_PROLOG 58 brk 0xC471 59 ret 60 61 .globl EXT(arm64_panic_lockdown_test_pac_brk_c472) 62LEXT(arm64_panic_lockdown_test_pac_brk_c472) 63 ARM64_PROLOG 64 brk 0xC472 65 ret 66 67 .globl EXT(arm64_panic_lockdown_test_pac_brk_c473) 68LEXT(arm64_panic_lockdown_test_pac_brk_c473) 69 ARM64_PROLOG 70 brk 0xC473 71 ret 72 73 .globl EXT(arm64_panic_lockdown_test_telemetry_brk_ff00) 74LEXT(arm64_panic_lockdown_test_telemetry_brk_ff00) 75 ARM64_PROLOG 76 brk 0xFF00 77 ret 78 79 .globl EXT(arm64_panic_lockdown_test_br_auth_fail) 80LEXT(arm64_panic_lockdown_test_br_auth_fail) 81 ARM64_PROLOG 82 braaz x0 83 ret 84 85 .globl EXT(arm64_panic_lockdown_test_ldr_auth_fail) 86LEXT(arm64_panic_lockdown_test_ldr_auth_fail) 87 ARM64_PROLOG 88 ldraa x0, [x0] 89 ret 90#endif /* ptrauth_calls */ 91 92#if __ARM_ARCH_8_6__ 93 .globl EXT(arm64_panic_lockdown_test_fpac) 94LEXT(arm64_panic_lockdown_test_fpac) 95 ARM64_PROLOG 96 autiza x0 97 ret 98#endif /* __ARM_ARCH_8_6__ */ 99 100#if BTI_ENFORCED && CONFIG_BTI_TELEMETRY 101 .globl EXT(arm64_panic_lockdown_test_bti_telemetry) 102LEXT(arm64_panic_lockdown_test_bti_telemetry) 103 ARM64_PROLOG 104 /* 105 * Trigger a BTI exception on the first instruction *after* the landing pad. 106 */ 1070: 108 nop 109 adr x0, 0b 110 br x0 111#endif /* BTI_ENFORCED && CONFIG_BTI_TELEMETRY */ 112 113/* 114 * SP1 Panic Lockdown Tests 115 * 116 * These tests are somewhat complex because we're round tripping through an 117 * exception vector which is not intended to return. This means we'll lose a 118 * fair amount of state. The only thing we can really rely on being preserved is 119 * SP_EL0 as we stay on SP1 for the entire vector. As such, we need to save all 120 * callee saved registers here. 121 */ 122 123.macro SAVE_CALLEE_REGISTERS 124 stp x19, x20, [sp, #-(16 * 10)]! 125 stp x21, x22, [sp, #0x10] 126 stp x23, x24, [sp, #0x20] 127 stp x25, x26, [sp, #0x30] 128 stp x27, x28, [sp, #0x40] 129 stp x29, x30, [sp, #0x50] 130 stp q4, q5, [sp, #0x60] 131 stp q6, q7, [sp, #0x80] 132.endmacro 133 134.macro LOAD_CALLEE_REGISTERS 135 ldp x21, x22, [sp, #0x10] 136 ldp x23, x24, [sp, #0x20] 137 ldp x25, x26, [sp, #0x30] 138 ldp x27, x28, [sp, #0x40] 139 ldp x29, x30, [sp, #0x50] 140 ldp q4, q5, [sp, #0x60] 141 ldp q6, q7, [sp, #0x80] 142 ldp x19, x20, [sp], #(16*10) 143.endmacro 144 145/** 146 * arm64_panic_lockdown_test_sp1_invalid_stack 147 * 148 * This test simulates a stack overflow/corruption 149 */ 150 .globl EXT(arm64_panic_lockdown_test_sp1_invalid_stack) 151LEXT(arm64_panic_lockdown_test_sp1_invalid_stack) 152 ARM64_STACK_PROLOG 153 SAVE_CALLEE_REGISTERS 154 /* Spill the real SP1 to the stack and trash the old one */ 155 msr SPSel, #1 156 mov x0, sp 157 mov x1, #0 158 mov sp, x1 159 msr SPSel, #0 160 str x0, [sp, #-16]! 161 /* Take an exception on SP1 but outside the critical region */ 162 msr SPSel, #1 163 b EXT(arm64_panic_lockdown_test_pac_brk_c470) 164 165 .global EXT(arm64_panic_lockdown_test_sp1_invalid_stack_handler) 166LEXT(arm64_panic_lockdown_test_sp1_invalid_stack_handler) 167 /* If we made it here, the test passed. Fix the system up. */ 168 mrs x0, SP_EL0 169 ldr x1, [x0], #16 170 /* Restore the real SP1 */ 171 mov sp, x1 172 /* Update SP0 to prepare to return */ 173 msr SPSel, #0 174 mov sp, x0 175 /* Return 1 to indicate success */ 176 mov x0, #1 177 LOAD_CALLEE_REGISTERS 178 ARM64_STACK_EPILOG 179 180/** 181 * arm64_panic_lockdown_test_sp1_exception_in_vector 182 * This test simulates an exception in the SP1 critical region 183 */ 184 .globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector) 185LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector) 186 ARM64_STACK_PROLOG 187 SAVE_CALLEE_REGISTERS 188 /* Trigger an exception inside the vector on SP1 */ 189 msr SPSel, #1 190 b EXT(el1_sp1_synchronous_raise_exception_in_vector) 191 192 .globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler) 193LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler) 194 /* Return to SP0 */ 195 msr SPSel, #0 196 /* Return 1 to indicate success */ 197 mov x0, #1 198 LOAD_CALLEE_REGISTERS 199 ARM64_STACK_EPILOG 200 201#endif /* CONFIG_SPTM */ 202 203#if BTI_ENFORCED 204 .text 205 .align 2 206 .global EXT(arm64_bti_test_jump_shim) 207LEXT(arm64_bti_test_jump_shim) 208 ARM64_PROLOG 209#if __has_feature(ptrauth_calls) 210 braaz x0 211#else 212 br x0 213#endif /* __has_feature(ptrauth_calls) */ 214 215 .global EXT(arm64_bti_test_call_shim) 216LEXT(arm64_bti_test_call_shim) 217 ARM64_STACK_PROLOG 218 PUSH_FRAME 219#if __has_feature(ptrauth_calls) 220 blraaz x0 221#else 222 blr x0 223#endif /* __has_feature(ptrauth_calls) */ 224 POP_FRAME 225 ARM64_STACK_EPILOG 226 227 .globl EXT(arm64_bti_test_func_with_no_landing_pad) 228LEXT(arm64_bti_test_func_with_no_landing_pad) 229 mov x0, #1 230 ret 231 232 .globl EXT(arm64_bti_test_func_with_call_landing_pad) 233LEXT(arm64_bti_test_func_with_call_landing_pad) 234 bti c 235 mov x0, #2 236 ret 237 238 .globl EXT(arm64_bti_test_func_with_jump_landing_pad) 239LEXT(arm64_bti_test_func_with_jump_landing_pad) 240 bti j 241 mov x0, #3 242 ret 243 244 .globl EXT(arm64_bti_test_func_with_jump_call_landing_pad) 245LEXT(arm64_bti_test_func_with_jump_call_landing_pad) 246 bti jc 247 mov x0, #4 248 ret 249 250#if __has_feature(ptrauth_returns) 251 .globl EXT(arm64_bti_test_func_with_pac_landing_pad) 252LEXT(arm64_bti_test_func_with_pac_landing_pad) 253 pacibsp 254 mov x0, #5 255 retab 256#endif /* __has_feature(ptrauth_returns) */ 257#endif /* BTI_ENFORCED */ 258