• Home
  • History
  • Annotate
  • 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  /* Tests for ARM64 FEAT_BTI (Branch Target Identification)
25   *  This is a mandatory CPU feature at ARM-A v8.5.  Prior to that level, the
26   *  BTI instructions are treated as NOPs and there is no enforcement.
27   *  The test here will check either case, based on build configuration and
28   *  runtime target support.
29   * Since this is an ARM64 feature, this should not be built for other arches.
30   */
31  #ifndef ARCH_ARM64
32  #error BTI is an ARM64 feature
33  #endif
34  
35  #include "btitest.h"
36  #include <arch/ops.h>
37  #include <err.h>
38  #include <lib/unittest/unittest.h>
39  #include <lk/init.h>
40  #include <stdio.h>
41  
42  /** Assembly relative function call test of all BTI-relevant calls.
43   */
44  int btitest_bl(void);
45  
46  /* Assembly indirect call functions, using all BTI-relevant calls.
47   *  BR via x16 and x17 is often used by linkers for veneers and has some
48   *  additional handling described in the ARM Architecture Reference Manual,
49   *  Table D8-36 (IYWFHD).
50   * The passed func_idx should be one of the BTITEST_CALLEE_ macros, which covers
51   *  the landing pad instruction types given in the ARM Architecture Reference
52   *  Manual, Table D8-37 (ICNBPL).
53   */
54  int btitest_blr(int func_idx);
55  int btitest_br_x16(int func_idx);
56  int btitest_br_x17(int func_idx);
57  int btitest_br(int func_idx);
58  
59  /* Get the expected return code when a BTI access should be trapped */
bti_trap_code(void)60  static int bti_trap_code(void) {
61  #ifdef KERNEL_BTI_ENABLED
62      if (arch_bti_supported()) {
63          return ERR_FAULT;
64      }
65  #endif
66      /* No BTI, or not enabled - faults are not detected */
67      return 0;
68  }
69  
TEST(btitest,supported)70  TEST(btitest, supported) {
71      if (!arch_bti_supported()) {
72          trusty_unittest_printf("[   INFO   ] BTI is not supported\n");
73          GTEST_SKIP();
74      }
75      EXPECT_EQ(true, arch_bti_supported());
76  test_abort:;
77  }
78  
79  /* Smoke-test the callee functions; they should return 0 when called with BL */
TEST(btitest,smoke)80  TEST(btitest, smoke) {
81      EXPECT_EQ(0, btitest_bl());
82  }
83  
TEST(btitest,nop)84  TEST(btitest, nop) {
85      /* Fault on jump or call to non-bti target */
86      EXPECT_EQ(bti_trap_code(), btitest_br(BTITEST_CALLEE_NOP));
87      EXPECT_EQ(bti_trap_code(), btitest_blr(BTITEST_CALLEE_NOP));
88      EXPECT_EQ(bti_trap_code(), btitest_br_x16(BTITEST_CALLEE_NOP));
89      EXPECT_EQ(bti_trap_code(), btitest_br_x17(BTITEST_CALLEE_NOP));
90  }
91  
TEST(btitest,bti)92  TEST(btitest, bti) {
93      /* Fault on any jump or call to non-target bti */
94      EXPECT_EQ(bti_trap_code(), btitest_br(BTITEST_CALLEE_BTI));
95      EXPECT_EQ(bti_trap_code(), btitest_blr(BTITEST_CALLEE_BTI));
96      EXPECT_EQ(bti_trap_code(), btitest_br_x16(BTITEST_CALLEE_BTI));
97      EXPECT_EQ(bti_trap_code(), btitest_br_x17(BTITEST_CALLEE_BTI));
98  }
99  
TEST(btitest,bti_c)100  TEST(btitest, bti_c) {
101      /* Call or branch via x16/17 to a call target is valid */
102      EXPECT_EQ(0, btitest_blr(BTITEST_CALLEE_BTI_C));
103      EXPECT_EQ(0, btitest_br_x16(BTITEST_CALLEE_BTI_C));
104      EXPECT_EQ(0, btitest_br_x17(BTITEST_CALLEE_BTI_C));
105  
106      /* Fault on branch to call target */
107      EXPECT_EQ(bti_trap_code(), btitest_br(BTITEST_CALLEE_BTI_C));
108  }
109  
TEST(btitest,bti_j)110  TEST(btitest, bti_j) {
111      /* Any branch to jump target is valid */
112      EXPECT_EQ(0, btitest_br(BTITEST_CALLEE_BTI_J));
113      EXPECT_EQ(0, btitest_br_x16(BTITEST_CALLEE_BTI_J));
114      EXPECT_EQ(0, btitest_br_x17(BTITEST_CALLEE_BTI_J));
115  
116      /* Fault on call to jump target */
117      EXPECT_EQ(bti_trap_code(), btitest_blr(BTITEST_CALLEE_BTI_J));
118  }
119  
TEST(btitest,bti_jc)120  TEST(btitest, bti_jc) {
121      /* Either branch type allowed to call and jump target */
122      EXPECT_EQ(0, btitest_br(BTITEST_CALLEE_BTI_JC));
123      EXPECT_EQ(0, btitest_br_x16(BTITEST_CALLEE_BTI_JC));
124      EXPECT_EQ(0, btitest_br_x17(BTITEST_CALLEE_BTI_JC));
125      EXPECT_EQ(0, btitest_blr(BTITEST_CALLEE_BTI_JC));
126  }
127  
TEST(btitest,pacisp)128  TEST(btitest, pacisp) {
129      if (!arch_pac_address_supported()) {
130          trusty_unittest_printf("[   INFO   ] PAC is not supported\n");
131          GTEST_SKIP();
132      }
133  
134      /* PACIASP is a valid target for all branch types */
135      EXPECT_EQ(0, btitest_br(BTITEST_CALLEE_PACIASP));
136      EXPECT_EQ(0, btitest_br_x16(BTITEST_CALLEE_PACIASP));
137      EXPECT_EQ(0, btitest_br_x17(BTITEST_CALLEE_PACIASP));
138      EXPECT_EQ(0, btitest_blr(BTITEST_CALLEE_PACIASP));
139  
140      /* PACIBSP is a valid target for all branch types */
141      EXPECT_EQ(0, btitest_br(BTITEST_CALLEE_PACIBSP));
142      EXPECT_EQ(0, btitest_br_x16(BTITEST_CALLEE_PACIBSP));
143      EXPECT_EQ(0, btitest_br_x17(BTITEST_CALLEE_PACIBSP));
144      EXPECT_EQ(0, btitest_blr(BTITEST_CALLEE_PACIBSP));
145  test_abort:;
146  }
147  
148  PORT_TEST(btitest, "com.android.kernel.btitest");
149