1- From 4900a67c4daabedbf83b563d77830c3f1c6eb599 Mon Sep 17 00:00:00 2001
2- From: Gilles Duboscq <gilles.m.duboscq@oracle.com>
3- Date: Wed, 23 Apr 2025 18:45:10 +0200
4- Subject: [PATCH 2/3] Add support __SANDBOX_SWCFI__ in unix64.S and win64.S
1+ From 0e770017b54a270b80a4c696703e79560f263541 Mon Sep 17 00:00:00 2001
2+ From: Matthias Neugschwandtner <matthias.neugschwandtner@oracle.com>
3+ Date: Wed, 10 Sep 2025 14:54:12 +0200
4+ Subject: [PATCH 2/3] Add support __SANDBOX_CFI__ in unix64.S and win64.S
5+
6+ This mode adds a check for jump targets to match the ENDBR64 instruction.
7+ The check is either performed entirely in software, or supported by the CPU.
8+
9+ Co-authored-by: Gilles Duboscq <gilles.m.duboscq@oracle.com>
510
6- This mode requires a software check for jump targets.
711---
812 src/x86/internal64.h | 4 +++
9- src/x86/unix64.S | 30 ++++++++++++++++++++
10- src/x86/win64.S | 65 +++++++++++++++++++++++++++++++++++++++++++-
11- 3 files changed, 98 insertions(+), 1 deletion (-)
13+ src/x86/unix64.S | 54 +++++++++++++++++++++++++++++--
14+ src/x86/win64.S | 77 +++++++++++++++++++++++++++++++++++++++++++-
15+ 3 files changed, 131 insertions(+), 4 deletions (-)
1216
1317diff --git a/src/x86/internal64.h b/src/x86/internal64.h
1418index 282b408..7142645 100644
@@ -27,10 +31,25 @@ index 282b408..7142645 100644
2731 #define UNIX64_TRAMP_SIZE 32
2832 #endif
2933diff --git a/src/x86/unix64.S b/src/x86/unix64.S
30- index d9c5bd4..10d9c8d 100644
34+ index d9c5bd4..3239ea3 100644
3135--- a/src/x86/unix64.S
3236+++ b/src/x86/unix64.S
33- @@ -98,6 +98,13 @@ L(ret_from_load_sse):
37+ @@ -39,7 +39,13 @@
38+ actual table. The entry points into the table are all 8 bytes.
39+ The use of ORG asserts that we're at the correct location. */
40+ /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
41+ - #ifdef __CET__
42+ + #ifdef __SANDBOX_SWCFI__
43+ + /* Increase slot size to accomodate ENDBR64 (+4 bytes) and SWCFI pattern (+24 bytes) for ret. */
44+ + # define E(BASE, X) .balign 8; .org BASE + (X) * 40
45+ + #elif defined __SANDBOX_HWCFI__
46+ + /* Increase slot size to accomodate ENDBR64 (+4 bytes) and HWCFI pattern (+6 bytes) for ret. */
47+ + # define E(BASE, X) .balign 8; .org BASE + (X) * 24
48+ + #elif defined __CET__
49+ /* Double slot size to 16 byte to add 4 bytes of ENDBR64. */
50+ # define E(BASE, X) .balign 8; .org BASE + X * 16
51+ #elif defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
52+ @@ -98,6 +104,13 @@ L(ret_from_load_sse):
3453
3554 /* Deallocate the reg arg area, except for r10, then load via pop. */
3655 leaq 0xb8(%r10), %rsp
@@ -44,7 +63,19 @@ index d9c5bd4..10d9c8d 100644
4463 popq %r10
4564
4665 /* Call the user function. */
47- @@ -126,6 +133,13 @@ L(UW2):
66+ @@ -119,13 +132,24 @@ L(UW2):
67+ movzbl %cl, %r10d
68+ leaq L(store_table)(%rip), %r11
69+ ja L(sa)
70+ - #ifdef __CET__
71+ + #ifdef __SANDBOX_SWCFI__
72+ + lea (%r10, %r10, 4), %r10
73+ + #elif defined __SANDBOX_HWCFI__
74+ + lea (%r10, %r10, 2), %r10
75+ + #elif defined __CET__
76+ /* NB: Originally, each slot is 8 byte. 4 bytes of ENDBR64 +
77+ 4 bytes NOP padding double slot size to 16 bytes. */
78+ addl %r10d, %r10d
4879 #endif
4980 leaq (%r11, %r10, 8), %r10
5081
@@ -58,7 +89,18 @@ index d9c5bd4..10d9c8d 100644
5889 /* Prep for the structure cases: scratch area in redzone. */
5990 leaq -20(%rsp), %rsi
6091 jmp *%r10
61- @@ -318,6 +332,13 @@ L(UW10):
92+ @@ -312,12 +336,25 @@ L(UW10):
93+ movzbl %al, %r10d
94+ leaq L(load_table)(%rip), %r11
95+ ja L(la)
96+ - #ifdef __CET__
97+ + #ifdef __SANDBOX_SWCFI__
98+ + lea (%r10, %r10, 4), %r10
99+ + #elif defined __SANDBOX_HWCFI__
100+ + lea (%r10, %r10, 2), %r10
101+ + #elif defined __CET__
102+ /* NB: Originally, each slot is 8 byte. 4 bytes of ENDBR64 +
103+ 4 bytes NOP padding double slot size to 16 bytes. */
62104 addl %r10d, %r10d
63105 #endif
64106 leaq (%r11, %r10, 8), %r10
@@ -68,11 +110,13 @@ index d9c5bd4..10d9c8d 100644
68110+ jz 1f
69111+ int3
70112+ 1:
113+ + #elif defined __SANDBOX_HWCFI__
114+ + test %r10, (%r10)
71115+ #endif
72116 leaq ffi_closure_RED_RVALUE(%rsp), %rsi
73117 jmp *%r10
74118
75- @@ -538,6 +559,15 @@ C(trampoline_code_table):
119+ @@ -538,6 +575,17 @@ C(trampoline_code_table):
76120 movl X86_CODE_OFFSET(%rip), %r10d /* Copy code into %r10 */
77121 #else
78122 movq X86_CODE_OFFSET(%rip), %r10 /* Copy code into %r10 */
@@ -85,26 +129,31 @@ index d9c5bd4..10d9c8d 100644
85129+ int3
86130+ 1:
87131+ popq %rdi
132+ + #elif defined __SANDBOX_HWCFI__
133+ + test %r10, (%r10)
88134 #endif
89135 jmp *%r10 /* Jump to code */
90136 .align 8
91137diff --git a/src/x86/win64.S b/src/x86/win64.S
92- index 58ec6a1..d1a180a 100644
138+ index 58ec6a1..8b142d9 100644
93139--- a/src/x86/win64.S
94140+++ b/src/x86/win64.S
95- @@ -27,7 +27,10 @@
141+ @@ -27,7 +27,13 @@
96142 actual table. The entry points into the table are all 8 bytes.
97143 The use of ORG asserts that we're at the correct location. */
98144 /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
99145- #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
100146+ #ifdef __SANDBOX_SWCFI__
101- + /* Triple slot size to 24 byte to add ENDBR64 and jump for ret. */
147+ + /* Increase slot size to accomodate ENDBR64 (+4 bytes) and SWCFI pattern (+24 bytes) for ret. */
148+ + # define E(BASE, X) .balign 8; .org BASE + (X) * 40
149+ + #elif defined __SANDBOX_HWCFI__
150+ + /* Increase slot size to accomodate ENDBR64 (+4 bytes) and HWCFI pattern (+6 bytes) for ret. */
102151+ # define E(BASE, X) .balign 8; .org BASE + (X) * 24
103152+ #elif defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
104153 # define E(BASE, X) .balign 8
105154 #else
106155 # define E(BASE, X) .balign 8; .org BASE + (X) * 8
107- @@ -73,18 +76,58 @@ C(ffi_call_win64):
156+ @@ -73,18 +79,67 @@ C(ffi_call_win64):
108157 movq 24(%rsp), %r9
109158 movsd 24(%rsp), %xmm3
110159
@@ -118,6 +167,10 @@ index 58ec6a1..d1a180a 100644
118167+ 1:
119168+ popq %r10
120169+ call *%r11
170+ + #elif defined __SANDBOX_HWCFI__
171+ + movq 16(%rbp), %r11
172+ + test %r11, (%r11)
173+ + call *%r11
121174+ #else
122175 call *16(%rbp)
123176+ #endif
@@ -127,19 +180,24 @@ index 58ec6a1..d1a180a 100644
127180 leaq 0f(%rip), %r10
128181 cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx
129182+
130- + #ifdef __SANDBOX_SWCFI__
131- + /* avoid leave in this mode, use larger slots (3 *8) */
183+ + #ifdef __SANDBOX_CFI__
184+ + /* avoid leave in this mode, use larger slots (5 *8) */
132185+ ja 99f
133- + movl %ecx, %r11d
134- + addl %ecx, %ecx
135- + addl %r11d, %ecx
186+ + #ifdef __SANDBOX_SWCFI__
187+ + lea (%rcx, %rcx, 4), %rcx
136188+ leaq (%r10, %rcx, 8), %r10
137189+ movl (%r10), %ecx
138190+ addl $0x5e1f00d, %ecx
139191+ jz 1f
140192+ int3
141193+ 1:
142194+ jmp *%r10
195+ + #elif defined __SANDBOX_HWCFI__
196+ + lea (%rcx, %rcx, 2), %rcx
197+ + leaq (%r10, %rcx, 8), %r10
198+ + test %r10, (%r10)
199+ + jmp *%r10
200+ + #endif /* SWCFI/HWCFI */
143201+
144202+ #define jmp_target \
145203+ _CET_ENDBR
@@ -163,7 +221,7 @@ index 58ec6a1..d1a180a 100644
163221 #define epilogue \
164222 leaveq; \
165223 cfi_remember_state; \
166- @@ -92,66 +135 ,86 @@ C(ffi_call_win64):
224+ @@ -92,66 +147 ,86 @@ C(ffi_call_win64):
167225 cfi_restore(%rbp); \
168226 ret; \
169227 cfi_restore_state
@@ -251,5 +309,5 @@ index 58ec6a1..d1a180a 100644
251309 epilogue
252310
253311- -
254- 2.43.0
312+ 2.34.1
255313
0 commit comments