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 ARM64_PROLOG 168 /* If we made it here, the test passed. Fix the system up. */ 169 mrs x0, SP_EL0 170 ldr x1, [x0], #16 171 /* Restore the real SP1 */ 172 mov sp, x1 173 /* Update SP0 to prepare to return */ 174 msr SPSel, #0 175 mov sp, x0 176 /* Return 1 to indicate success */ 177 mov x0, #1 178 LOAD_CALLEE_REGISTERS 179 ARM64_STACK_EPILOG 180 181/** 182 * arm64_panic_lockdown_test_sp1_exception_in_vector 183 * This test simulates an exception in the SP1 critical region 184 */ 185 .globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector) 186LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector) 187 ARM64_STACK_PROLOG 188 SAVE_CALLEE_REGISTERS 189 /* Trigger an exception inside the vector on SP1 */ 190 msr SPSel, #1 191 b EXT(el1_sp1_synchronous_raise_exception_in_vector) 192 193 .globl EXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler) 194LEXT(arm64_panic_lockdown_test_sp1_exception_in_vector_handler) 195 ARM64_PROLOG 196 /* Return to SP0 */ 197 msr SPSel, #0 198 /* Return 1 to indicate success */ 199 mov x0, #1 200 LOAD_CALLEE_REGISTERS 201 ARM64_STACK_EPILOG 202 203#endif /* CONFIG_SPTM */ 204 205#if BTI_ENFORCED 206 .text 207 .align 2 208 .global EXT(arm64_bti_test_jump_shim) 209LEXT(arm64_bti_test_jump_shim) 210 ARM64_PROLOG 211#if __has_feature(ptrauth_calls) 212 braaz x0 213#else 214 br x0 215#endif /* __has_feature(ptrauth_calls) */ 216 217 .global EXT(arm64_bti_test_call_shim) 218LEXT(arm64_bti_test_call_shim) 219 ARM64_STACK_PROLOG 220 PUSH_FRAME 221#if __has_feature(ptrauth_calls) 222 blraaz x0 223#else 224 blr x0 225#endif /* __has_feature(ptrauth_calls) */ 226 POP_FRAME 227 ARM64_STACK_EPILOG 228 229 .globl EXT(arm64_bti_test_func_with_no_landing_pad) 230LEXT(arm64_bti_test_func_with_no_landing_pad) 231 mov x0, #1 232 ret 233 234 .globl EXT(arm64_bti_test_func_with_call_landing_pad) 235LEXT(arm64_bti_test_func_with_call_landing_pad) 236 bti c 237 mov x0, #2 238 ret 239 240 .globl EXT(arm64_bti_test_func_with_jump_landing_pad) 241LEXT(arm64_bti_test_func_with_jump_landing_pad) 242 bti j 243 mov x0, #3 244 ret 245 246 .globl EXT(arm64_bti_test_func_with_jump_call_landing_pad) 247LEXT(arm64_bti_test_func_with_jump_call_landing_pad) 248 bti jc 249 mov x0, #4 250 ret 251 252#if __has_feature(ptrauth_returns) 253 .globl EXT(arm64_bti_test_func_with_pac_landing_pad) 254LEXT(arm64_bti_test_func_with_pac_landing_pad) 255 pacibsp 256 mov x0, #5 257 retab 258#endif /* __has_feature(ptrauth_returns) */ 259#endif /* BTI_ENFORCED */ 260