• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022, Google Inc. All rights reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <asm.h>
25#include <arch/asm_macros.h>
26#include <err.h>
27#include "btitest.h"
28
29.section .text
30
31/* Fault handler to return where BTI calls fail.
32 * On return from the caught Branch Target exception, PSTATE.BTYPE will still
33 * be set according to the last branch taken.  Therefore we need to land on a
34 * BTI jc to be compatible with all callers - and avoid another immediate
35 * Branch Target exception.
36 */
37.Lbtitest_callee_fault:
38    bti jc
39    mov x0, #ERR_FAULT
40    ret
41
42/**
43 * int btitest_bl(void) - Use bl to call each of the test functions
44 *
45 * This calls each of the test functions using bl and a relative offset,
46 * which should always be allowed.  The functions are expected to all return 0.
47 *
48 * Returns The first non-zero return code, or 0 if all functions pass.
49 */
50FUNCTION(btitest_bl)
51    push lr, xzr
52    bl btitest_callee_nop
53    cbnz x0, .Lerror
54    bl btitest_callee_bti
55    cbnz x0, .Lerror
56    bl btitest_callee_bti_c
57    cbnz x0, .Lerror
58    bl btitest_callee_bti_j
59    cbnz x0, .Lerror
60    bl btitest_callee_bti_jc
61    cbnz x0, .Lerror
62    bl btitest_callee_paciasp
63    cbnz x0, .Lerror
64    bl btitest_callee_pacibsp
65.Lerror:
66    pop lr, xzr
67    ret
68
69/**
70 * int btitest_blr(int) - Use blr to call the passed function
71 *
72 * Returns The called function's return value
73 */
74FUNCTION(btitest_blr)
75    push lr, xzr
76    bl get_callee
77    blr x0
78    pop lr, xzr
79    ret
80
81/**
82 * int btitest_br(int) - Use br to call the passed function via the x0 register
83 *
84 * Returns The called function's return value
85 */
86FUNCTION(btitest_br)
87    push lr, xzr
88    bl get_callee
89    pop lr, xzr
90    br x0
91
92/**
93 * int btitest_br_x16(int) - Use br to call the passed function via the x16
94 *                           register
95 *
96 * Returns The called function's return value
97 */
98FUNCTION(btitest_br_x16)
99    push lr, xzr
100    bl get_callee
101    pop lr, xzr
102    mov x16, x0
103    br x16
104
105/**
106 * int btitest_br_x17(int) - Use br to call the passed function via the x17
107 *                           register
108 *
109 * Returns The called function's return value
110 */
111FUNCTION(btitest_br_x17)
112    push lr, xzr
113    bl get_callee
114    pop lr, xzr
115    mov x17, x0
116    br x17
117
118/**
119 * int btitest_callee_nop(void) - Function with nop instruction
120 *
121 * Returns ERR_FAULT if the BTI check fails.
122 * Return 0 if the BTI check passes.
123 */
124LOCAL_FUNCTION(btitest_callee_nop)
125    set_fault_handler .Lbtitest_callee_fault
126    nop
127    mov	x0, #0
128    ret
129
130/**
131 * int btitest_callee_bti(void) - Function with bti instruction
132 *
133 * Returns ERR_FAULT if the BTI check fails.
134 * Return 0 if the BTI check passes.
135 */
136LOCAL_FUNCTION(btitest_callee_bti)
137    set_fault_handler .Lbtitest_callee_fault
138    bti
139    mov	x0, #0
140    ret
141
142/**
143 * int btitest_callee_bti_c(void) - Function with bti c instruction
144 *
145 * Returns ERR_FAULT if the BTI check fails.
146 * Return 0 if the BTI check passes.
147 */
148LOCAL_FUNCTION(btitest_callee_bti_c)
149    set_fault_handler .Lbtitest_callee_fault
150    bti c
151    mov	x0, #0
152    ret
153
154/**
155 * int btitest_callee_bti_j(void) - Function with bti j instruction
156 *
157 * Returns ERR_FAULT if the BTI check fails.
158 * Return 0 if the BTI check passes.
159 */
160LOCAL_FUNCTION(btitest_callee_bti_j)
161    set_fault_handler .Lbtitest_callee_fault
162    bti j
163    mov	x0, #0
164    ret
165
166/**
167 * int btitest_callee_bti_jc(void) - Function with bti jc instruction
168 *
169 * Returns ERR_FAULT if the BTI check fails.
170 * Return 0 if the BTI check passes.
171 */
172LOCAL_FUNCTION(btitest_callee_bti_jc)
173    set_fault_handler .Lbtitest_callee_fault
174    bti jc
175    mov	x0, #0
176    ret
177
178/**
179 * int btitest_callee_paciasp(void) - Function with paciasp instruction
180 *
181 * Returns ERR_FAULT if the BTI check fails.
182 * Return 0 if the BTI check passes.
183 */
184LOCAL_FUNCTION(btitest_callee_paciasp)
185    set_fault_handler .Lbtitest_callee_fault
186    paciasp
187    mov	x0, #0
188    autiasp
189    ret
190
191/**
192 * int btitest_callee_pacibsp(void) - Function with pacibsp instruction
193 *
194 * Returns ERR_FAULT if the BTI check fails.
195 * Return 0 if the BTI check passes.
196 */
197LOCAL_FUNCTION(btitest_callee_pacibsp)
198    set_fault_handler .Lbtitest_callee_fault
199    pacibsp
200    mov	x0, #0
201    autibsp
202    ret
203
204/**
205 * int btitest_callee_error(void) - Error function which always fails
206 *
207 * This is valid as any jump target.
208 *
209 * Returns ERR_INVALID_ARGS unconditionally.
210 */
211LOCAL_FUNCTION(btitest_callee_error)
212    bti jc
213    mov	x0, #ERR_INVALID_ARGS
214    ret
215
216/**
217 * get_callee(int) - Get the address of the callee function.
218 *
219 * Converts the passed function index into the function address.
220 * This is done here to avoid using the C compiler to get function addresses -
221 * the compiler may insert veneers or indirection under some situations (e.g.
222 * for CFI) and break the specific landing pad instructions needed to test BTI.
223 *
224 * Return 0 if the index is not recognised, otherwise the function address.
225 */
226LOCAL_FUNCTION(get_callee)
227    cmp w0, #BTITEST_CALLEE_NOP
228    bne .Ltry_bti
229    adr x0, btitest_callee_nop
230    ret
231.Ltry_bti:
232    cmp w0, #BTITEST_CALLEE_BTI
233    bne .Ltry_bti_c
234    adr x0, btitest_callee_bti
235    ret
236.Ltry_bti_c:
237    cmp w0, #BTITEST_CALLEE_BTI_C
238    bne .Ltry_bti_j
239    adr x0, btitest_callee_bti_c
240    ret
241.Ltry_bti_j:
242    cmp w0, #BTITEST_CALLEE_BTI_J
243    bne .Ltry_bti_jc
244    adr x0, btitest_callee_bti_j
245    ret
246.Ltry_bti_jc:
247    cmp w0, #BTITEST_CALLEE_BTI_JC
248    bne .Ltry_paciasp
249    adr x0, btitest_callee_bti_jc
250    ret
251.Ltry_paciasp:
252    cmp w0, #BTITEST_CALLEE_PACIASP
253    bne .Ltry_pacibsp
254    adr x0, btitest_callee_paciasp
255    ret
256.Ltry_pacibsp:
257    cmp w0, #BTITEST_CALLEE_PACIBSP
258    bne .Lunknown
259    adr x0, btitest_callee_pacibsp
260    ret
261.Lunknown:
262    /* Return error function which unconditionally fails any test */
263    adr x0, btitest_callee_error
264    ret
265