Warning: This file is not a C or C++ file. It does not have highlighting.
1 | /* Restartable Sequences Linux arm architecture header. |
---|---|
2 | Copyright (C) 2021-2024 Free Software Foundation, Inc. |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the License, or (at your option) any later version. |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <https://www.gnu.org/licenses/>. */ |
17 | |
18 | #ifndef _SYS_RSEQ_H |
19 | # error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." |
20 | #endif |
21 | |
22 | /* |
23 | RSEQ_SIG is a signature required before each abort handler code. |
24 | |
25 | It is a 32-bit value that maps to actual architecture code compiled |
26 | into applications and libraries. It needs to be defined for each |
27 | architecture. When choosing this value, it needs to be taken into |
28 | account that generating invalid instructions may have ill effects on |
29 | tools like objdump, and may also have impact on the CPU speculative |
30 | execution efficiency in some cases. |
31 | |
32 | - ARM little endian |
33 | |
34 | RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand |
35 | value 0x5de3. This traps if user-space reaches this instruction by mistake, |
36 | and the uncommon operand ensures the kernel does not move the instruction |
37 | pointer to attacker-controlled code on rseq abort. |
38 | |
39 | The instruction pattern in the A32 instruction set is: |
40 | |
41 | e7f5def3 udf #24035 ; 0x5de3 |
42 | |
43 | This translates to the following instruction pattern in the T16 instruction |
44 | set: |
45 | |
46 | little endian: |
47 | def3 udf #243 ; 0xf3 |
48 | e7f5 b.n <7f5> |
49 | |
50 | - ARMv6+ big endian (BE8): |
51 | |
52 | ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian |
53 | code and big-endian data. The data value of the signature needs to have its |
54 | byte order reversed to generate the trap instruction: |
55 | |
56 | Data: 0xf3def5e7 |
57 | |
58 | Translates to this A32 instruction pattern: |
59 | |
60 | e7f5def3 udf #24035 ; 0x5de3 |
61 | |
62 | Translates to this T16 instruction pattern: |
63 | |
64 | def3 udf #243 ; 0xf3 |
65 | e7f5 b.n <7f5> |
66 | |
67 | - Prior to ARMv6 big endian (BE32): |
68 | |
69 | Prior to ARMv6, -mbig-endian generates big-endian code and data |
70 | (which match), so the endianness of the data representation of the |
71 | signature should not be reversed. However, the choice between BE32 |
72 | and BE8 is done by the linker, so we cannot know whether code and |
73 | data endianness will be mixed before the linker is invoked. So rather |
74 | than try to play tricks with the linker, the rseq signature is simply |
75 | data (not a trap instruction) prior to ARMv6 on big endian. This is |
76 | why the signature is expressed as data (.word) rather than as |
77 | instruction (.inst) in assembler. */ |
78 | |
79 | #ifdef __ARMEB__ |
80 | # define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ |
81 | #else |
82 | # define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ |
83 | #endif |
84 |
Warning: This file is not a C or C++ file. It does not have highlighting.